From 4463f975e3a45ac8f8d9e66c218f24b1fd0b71f9 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Thu, 9 Aug 2018 17:55:11 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Koenig=20-=20Unsplash=20integration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs https://github.com/TryGhost/Ghost/issues/9724 - standardised `{{gh-unsplash}}` actions and action arguments to better represent a generic "image source" - added `{{gh-unsplash searchTerm="ghosts"}}` parameter - added `payload` param to `card` definitions used for plus/slash menus so that default payload params can be passed to cards - added a concept of "image selectors" to image card - if a `payload.imageSelector` param is received by the card it will look it up in it's list of known selectors and display the appropriate image selection component - if the card was created with an image selector param and the image selector is closed without selecting an image then the card will be removed - delete image cards during cleanup if they were created via selector but have no src --- .../admin/app/components/gh-image-uploader.js | 4 +-- .../app/components/gh-markdown-editor.js | 8 ++--- .../admin/app/components/gh-unsplash-photo.js | 6 ++-- ghost/admin/app/components/gh-unsplash.js | 24 +++++++++++++-- ghost/admin/app/services/unsplash.js | 28 ++++++++++-------- .../components/gh-image-uploader.hbs | 2 +- .../components/gh-markdown-editor.hbs | 2 +- .../components/gh-unsplash-photo.hbs | 2 +- .../app/templates/components/gh-unsplash.hbs | 7 +---- .../addon/components/koenig-card-image.js | 29 ++++++++++++++++++- .../addon/components/koenig-plus-menu.js | 2 +- .../addon/components/koenig-slash-menu.js | 4 +-- .../lib/koenig-editor/addon/options/cards.js | 11 +++++-- .../components/koenig-card-image.hbs | 7 +++++ 14 files changed, 96 insertions(+), 40 deletions(-) diff --git a/ghost/admin/app/components/gh-image-uploader.js b/ghost/admin/app/components/gh-image-uploader.js index 612014b221..62135fe111 100644 --- a/ghost/admin/app/components/gh-image-uploader.js +++ b/ghost/admin/app/components/gh-image-uploader.js @@ -128,8 +128,8 @@ export default Component.extend({ } }, - addUnsplashPhoto(photo) { - this.set('url', photo.urls.regular); + addUnsplashPhoto({src}) { + this.set('url', src); this.send('saveUrl'); }, diff --git a/ghost/admin/app/components/gh-markdown-editor.js b/ghost/admin/app/components/gh-markdown-editor.js index 4daa5786e1..a552ac3df4 100644 --- a/ghost/admin/app/components/gh-markdown-editor.js +++ b/ghost/admin/app/components/gh-markdown-editor.js @@ -363,11 +363,11 @@ export default Component.extend(ShortcutsMixin, { this.toggleProperty('_showUnsplash'); }, - insertUnsplashPhoto(photo) { + insertUnsplashPhoto({src, alt, caption}) { let image = { - alt: photo.description || '', - url: photo.urls.regular, - credit: `Photo by [${photo.user.name}](${photo.user.links.html}?utm_source=ghost&utm_medium=referral&utm_campaign=api-credit) / [Unsplash](https://unsplash.com/?utm_source=ghost&utm_medium=referral&utm_campaign=api-credit)` + alt, + url: src, + credit: `${caption}` }; this._insertImages([image]); diff --git a/ghost/admin/app/components/gh-unsplash-photo.js b/ghost/admin/app/components/gh-unsplash-photo.js index d3ca2d1a82..ba40465037 100644 --- a/ghost/admin/app/components/gh-unsplash-photo.js +++ b/ghost/admin/app/components/gh-unsplash-photo.js @@ -13,7 +13,7 @@ export default Component.extend({ zoomed: false, // closure actions - insert() {}, + select() {}, zoom() {}, style: computed('zoomed', function () { @@ -78,10 +78,10 @@ export default Component.extend({ }, actions: { - insert(event) { + select(event) { event.preventDefault(); event.stopPropagation(); - this.insert(this.get('photo')); + this.select(this.get('photo')); }, zoom(event) { diff --git a/ghost/admin/app/components/gh-unsplash.js b/ghost/admin/app/components/gh-unsplash.js index 80a4ce740b..515a2f909c 100644 --- a/ghost/admin/app/components/gh-unsplash.js +++ b/ghost/admin/app/components/gh-unsplash.js @@ -16,10 +16,11 @@ export default Component.extend(ShortcutsMixin, { shortcuts: null, tagName: '', zoomedPhoto: null, + searchTerm: null, // closure actions close() {}, - insert() {}, + select() {}, sideNavHidden: or('ui.{autoNav,isFullScreen,showMobileMenu}'), @@ -31,6 +32,16 @@ export default Component.extend(ShortcutsMixin, { }; }, + didReceiveAttrs() { + this._super(...arguments); + + if (this.searchTerm !== this._searchTerm) { + this.unsplash.updateSearch(this.searchTerm); + } + + this._searchTerm = this.searchTerm; + }, + didInsertElement() { this._super(...arguments); this._resizeCallback = bind(this, this._handleResize); @@ -63,9 +74,16 @@ export default Component.extend(ShortcutsMixin, { this.set('zoomedPhoto', null); }, - insert(photo) { + select(photo) { this.get('unsplash').triggerDownload(photo); - this.insert(photo); + + let selectParams = { + src: photo.urls.regular, + alt: photo.description || '', + caption: `Photo by ${photo.user.name} / Unsplash` + }; + this.select(selectParams); + this.close(); }, diff --git a/ghost/admin/app/services/unsplash.js b/ghost/admin/app/services/unsplash.js index 97c0ae0c7a..8608d86980 100644 --- a/ghost/admin/app/services/unsplash.js +++ b/ghost/admin/app/services/unsplash.js @@ -54,6 +54,21 @@ export default Service.extend({ return reject(); }, + updateSearch(term) { + if (term === this.get('searchTerm')) { + return; + } + + this.set('searchTerm', term); + this._reset(); + + if (term) { + return this.get('_search').perform(term); + } else { + return this.get('_loadNew').perform(); + } + }, + retryLastRequest() { return this.get('_retryLastRequest').perform(); }, @@ -75,18 +90,7 @@ export default Service.extend({ actions: { updateSearch(term) { - if (term === this.get('searchTerm')) { - return; - } - - this.set('searchTerm', term); - this._reset(); - - if (term) { - return this.get('_search').perform(term); - } else { - return this.get('_loadNew').perform(); - } + return this.updateSearch(term); } }, diff --git a/ghost/admin/app/templates/components/gh-image-uploader.hbs b/ghost/admin/app/templates/components/gh-image-uploader.hbs index d63e8c8f8c..3325aecf90 100644 --- a/ghost/admin/app/templates/components/gh-image-uploader.hbs +++ b/ghost/admin/app/templates/components/gh-image-uploader.hbs @@ -28,7 +28,7 @@ {{#if _showUnsplash}} {{gh-unsplash - insert=(action "addUnsplashPhoto") + select=(action "addUnsplashPhoto") close=(action (toggle "_showUnsplash" this)) }} {{/if}} diff --git a/ghost/admin/app/templates/components/gh-markdown-editor.hbs b/ghost/admin/app/templates/components/gh-markdown-editor.hbs index e0584d2325..aca142372c 100644 --- a/ghost/admin/app/templates/components/gh-markdown-editor.hbs +++ b/ghost/admin/app/templates/components/gh-markdown-editor.hbs @@ -23,7 +23,7 @@ {{#if _showUnsplash}} {{gh-unsplash - insert=(action "insertUnsplashPhoto") + select=(action "insertUnsplashPhoto") close=(action "toggleUnsplash")}} {{/if}} diff --git a/ghost/admin/app/templates/components/gh-unsplash-photo.hbs b/ghost/admin/app/templates/components/gh-unsplash-photo.hbs index 856c3c05bf..d9551921ea 100644 --- a/ghost/admin/app/templates/components/gh-unsplash-photo.hbs +++ b/ghost/admin/app/templates/components/gh-unsplash-photo.hbs @@ -15,7 +15,7 @@ {{photo.user.name}} - Insert image + Insert image diff --git a/ghost/admin/app/templates/components/gh-unsplash.hbs b/ghost/admin/app/templates/components/gh-unsplash.hbs index 4714b495bf..95a3e24639 100644 --- a/ghost/admin/app/templates/components/gh-unsplash.hbs +++ b/ghost/admin/app/templates/components/gh-unsplash.hbs @@ -40,7 +40,7 @@ {{#each unsplash.columns as |photos|}}
{{#each photos as |photo|}} - {{gh-unsplash-photo photo=photo zoom=(action "zoomPhoto") insert=(action "insert")}} + {{gh-unsplash-photo photo=photo zoom=(action "zoomPhoto") select=(action "select")}} {{/each}}
{{/each}} @@ -73,17 +73,12 @@ {{!-- zoomed image overlay --}} {{#if zoomedPhoto}} -<<<<<<< HEAD -
- {{gh-unsplash-photo photo=zoomedPhoto zoomed=true zoom=(action "closeZoom") insert=(action "insert")}} -=======
{{gh-unsplash-photo photo=zoomedPhoto zoomed=true zoom=(action "closeZoom") select=(action "select")}} ->>>>>>> 419884354... fixed zoom layout
{{/if}}
diff --git a/ghost/admin/lib/koenig-editor/addon/components/koenig-card-image.js b/ghost/admin/lib/koenig-editor/addon/components/koenig-card-image.js index 4d0631a93a..713c2d6017 100644 --- a/ghost/admin/lib/koenig-editor/addon/components/koenig-card-image.js +++ b/ghost/admin/lib/koenig-editor/addon/components/koenig-card-image.js @@ -6,7 +6,7 @@ import { IMAGE_EXTENSIONS, IMAGE_MIME_TYPES } from 'ghost-admin/components/gh-image-uploader'; -import {computed, set} from '@ember/object'; +import {computed, set, setProperties} from '@ember/object'; import {htmlSafe} from '@ember/string'; import {isEmpty} from '@ember/utils'; import {run} from '@ember/runloop'; @@ -32,11 +32,21 @@ export default Component.extend({ deselectCard() {}, editCard() {}, saveCard() {}, + deleteCard() {}, moveCursorToNextSection() {}, moveCursorToPrevSection() {}, addParagraphAfterCard() {}, registerComponent() {}, + imageSelector: computed('payload.imageSelector', function () { + let selector = this.payload.imageSelector; + let imageSelectors = { + unsplash: 'gh-unsplash' + }; + + return imageSelectors[selector]; + }), + counts: computed('payload.{src,caption}', function () { let wordCount = 0; let imageCount = 0; @@ -168,6 +178,23 @@ export default Component.extend({ resetSrcs() { this.set('previewSrc', null); this._updatePayloadAttr('src', null); + }, + + selectFromImageSelector({src, caption, alt}) { + let {payload, saveCard} = this; + let imageSelector, searchTerm; + + setProperties(payload, {src, caption, alt, imageSelector, searchTerm}); + + saveCard(payload, false); + }, + + closeImageSelector() { + if (!this.payload.src) { + return this.deleteCard(); + } + + set(this.payload, 'imageSelector', undefined); } }, diff --git a/ghost/admin/lib/koenig-editor/addon/components/koenig-plus-menu.js b/ghost/admin/lib/koenig-editor/addon/components/koenig-plus-menu.js index cd0e22d8e2..6e3d538c5c 100644 --- a/ghost/admin/lib/koenig-editor/addon/components/koenig-plus-menu.js +++ b/ghost/admin/lib/koenig-editor/addon/components/koenig-plus-menu.js @@ -96,7 +96,7 @@ export default Component.extend({ let range = this._editorRange; if (item.type === 'card') { - this.replaceWithCardSection(item.replaceArg, range); + this.replaceWithCardSection(item.replaceArg, range, item.payload); } this._hideButton(); diff --git a/ghost/admin/lib/koenig-editor/addon/components/koenig-slash-menu.js b/ghost/admin/lib/koenig-editor/addon/components/koenig-slash-menu.js index 10d5e17ccb..ee1098c1ba 100644 --- a/ghost/admin/lib/koenig-editor/addon/components/koenig-slash-menu.js +++ b/ghost/admin/lib/koenig-editor/addon/components/koenig-slash-menu.js @@ -1,6 +1,7 @@ import Component from '@ember/component'; import layout from '../templates/components/koenig-slash-menu'; import {CARD_MENU} from '../options/cards'; +import {assign} from '@ember/polyfills'; import {computed, set} from '@ember/object'; import {copy} from '@ember/object/internals'; import {htmlSafe} from '@ember/string'; @@ -91,7 +92,7 @@ export default Component.extend({ itemClicked(item, event) { let range = this._openRange.head.section.toRange(); let [, ...params] = this._query.split(/\s/); - let payload; + let payload = assign({}, item.payload); // make sure the click doesn't propagate and get picked up by the // newly inserted card which can then remove itself because it @@ -103,7 +104,6 @@ export default Component.extend({ // params are order-dependent and listed in CARD_MENU for each card if (!isEmpty(item.params) && !isEmpty(params)) { - payload = {}; item.params.forEach((param, i) => { payload[param] = params[i]; }); diff --git a/ghost/admin/lib/koenig-editor/addon/options/cards.js b/ghost/admin/lib/koenig-editor/addon/options/cards.js index ddf1da8775..76dccc919d 100644 --- a/ghost/admin/lib/koenig-editor/addon/options/cards.js +++ b/ghost/admin/lib/koenig-editor/addon/options/cards.js @@ -8,7 +8,9 @@ export default [ createComponentCard('embed', {hasEditMode: false, deleteIfEmpty: 'payload.html'}), createComponentCard('hr', {hasEditMode: false, selectAfterInsert: false}), createComponentCard('html', {deleteIfEmpty: 'payload.html'}), - createComponentCard('image', {hasEditMode: false}), + createComponentCard('image', {hasEditMode: false, deleteIfEmpty(card) { + return card.payload.imageSelector && !card.payload.src; + }}), createComponentCard('markdown', {deleteIfEmpty: 'payload.markdown'}) ]; @@ -89,8 +91,11 @@ export const CARD_MENU = [ iconClass: 'kg-card-type-unsplash', matches: ['unsplash'], type: 'card', - replaceArg: 'embed', - params: ['url'] + replaceArg: 'image', + params: ['searchTerm'], + payload: { + imageSelector: 'unsplash' + } }, { label: 'Vimeo', diff --git a/ghost/admin/lib/koenig-editor/addon/templates/components/koenig-card-image.hbs b/ghost/admin/lib/koenig-editor/addon/templates/components/koenig-card-image.hbs index abc5e724ef..76d7a4927a 100644 --- a/ghost/admin/lib/koenig-editor/addon/templates/components/koenig-card-image.hbs +++ b/ghost/admin/lib/koenig-editor/addon/templates/components/koenig-card-image.hbs @@ -71,4 +71,11 @@ placeholder="Type caption for image (optional)" }} {{/if}} + + {{#if imageSelector}} + {{component imageSelector + searchTerm=payload.searchTerm + select=(action "selectFromImageSelector") + close=(action "closeImageSelector")}} + {{/if}} {{/koenig-card}}