From fce4aa9176ff9f20582fbbcf8b47e7135182d1cd Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Tue, 23 Oct 2018 10:29:49 +0100 Subject: [PATCH] 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 --- .../admin/app/components/aspect-ratio-box.js | 51 +++++++++++++++++++ .../app/controllers/settings/integration.js | 32 +++++++++++- .../templates/components/aspect-ratio-box.hbs | 3 ++ .../app/templates/settings/integration.hbs | 47 ++++++++++++++--- 4 files changed, 125 insertions(+), 8 deletions(-) create mode 100644 ghost/admin/app/components/aspect-ratio-box.js create mode 100644 ghost/admin/app/templates/components/aspect-ratio-box.hbs diff --git a/ghost/admin/app/components/aspect-ratio-box.js b/ghost/admin/app/components/aspect-ratio-box.js new file mode 100644 index 0000000000..e8f429e4ac --- /dev/null +++ b/ghost/admin/app/components/aspect-ratio-box.js @@ -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); + }); + } + +}); diff --git a/ghost/admin/app/controllers/settings/integration.js b/ghost/admin/app/controllers/settings/integration.js index 59ec174d5c..c17d932702 100644 --- a/ghost/admin/app/controllers/settings/integration.js +++ b/ghost/admin/app/controllers/settings/integration.js @@ -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(); }, @@ -74,7 +104,7 @@ export default Controller.extend({ cancelIntegrationDeletion() { this.set('showDeleteIntegrationModal', false); }, - + confirmWebhookDeletion(webhook) { this.set('webhookToDelete', webhook); }, diff --git a/ghost/admin/app/templates/components/aspect-ratio-box.hbs b/ghost/admin/app/templates/components/aspect-ratio-box.hbs new file mode 100644 index 0000000000..724409a623 --- /dev/null +++ b/ghost/admin/app/templates/components/aspect-ratio-box.hbs @@ -0,0 +1,3 @@ +{{#unless isResizing}} +{{yield}} +{{/unless}} \ No newline at end of file diff --git a/ghost/admin/app/templates/settings/integration.hbs b/ghost/admin/app/templates/settings/integration.hbs index acc60875e0..8ed8982e74 100644 --- a/ghost/admin/app/templates/settings/integration.hbs +++ b/ghost/admin/app/templates/settings/integration.hbs @@ -12,12 +12,45 @@
-
- {{#unless integration.iconImage}} - {{svg-jar "integration" class="w-100"}} - {{/unless}} -
-
+
+ +
+ {{#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}} +
+ {{uploader.progressBar}} +
+ {{else}} + + {{/if}} +
+ {{gh-file-input + name="iconImage" + multiple=false + action=uploader.setFiles + accept=imageMimeTypes + data-test-file-input="icon"}} +
+ {{/gh-uploader}} +
+
+
{{#gh-validation-status-container class="flex flex-column w-100 mr3" errors=integration.errors @@ -184,7 +217,7 @@ close=(action "cancelIntegrationDeletion") modifier="action wide"}} {{/if}} - + {{#if webhookToDelete}} {{gh-fullscreen-modal "delete-webhook" confirm=(action "deleteWebhook")