Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
🎨 Enabled Unsplash integration by default (#862)
Browse files Browse the repository at this point in the history
no issue

- Unsplash integration is enabled by default for all users
- it's no longer necessary to create your own Unsplash application and configure your application ID
  • Loading branch information
kevinansfield authored and kirrg001 committed Sep 20, 2017
1 parent 4371142 commit 2e12987
Show file tree
Hide file tree
Showing 14 changed files with 37 additions and 278 deletions.
13 changes: 0 additions & 13 deletions app/components/gh-image-uploader.js
Expand Up @@ -6,7 +6,6 @@ import {
isUnsupportedMediaTypeError,
isVersionMismatchError
} from 'ghost-admin/services/ajax';
import {assign} from '@ember/polyfills';
import {computed} from '@ember/object';
import {htmlSafe} from '@ember/string';
import {inject as injectService} from '@ember/service';
Expand Down Expand Up @@ -79,18 +78,6 @@ export default Component.extend({
return htmlSafe(`width: ${width}`);
}),

// HACK: this settings/config dance is needed because the "override" only
// happens when visiting the unsplash app settings route
// TODO: move the override logic to the server, client knows too much
// about which values should override others
unsplash: computed('config.unsplashAPI', 'settings.unsplash', function () {
let unsplashConfig = this.get('config.unsplashAPI');
let unsplashSettings = this.get('settings.unsplash');
let unsplash = assign({}, unsplashConfig, unsplashSettings);

return unsplash;
}),

didReceiveAttrs() {
let image = this.get('image');
this.set('url', image);
Expand Down
10 changes: 1 addition & 9 deletions app/components/gh-markdown-editor.js
Expand Up @@ -149,15 +149,7 @@ export default Component.extend(ShortcutsMixin, {
status: ['words']
};

// if unsplash is active insert the toolbar button after the image button
// HACK: this settings/config dance is needed because the "override" only
// happens when visiting the unsplash app settings route
// TODO: move the override logic to the server, client knows too much
// about which values should override others
let unsplashConfig = this.get('config.unsplashAPI');
let unsplashSettings = this.get('settings.unsplash');
let unsplash = assign({}, unsplashConfig, unsplashSettings);
if (unsplash.isActive) {
if (this.get('settings.unsplash.isActive')) {
let image = defaultOptions.toolbar.findBy('name', 'image');
let index = defaultOptions.toolbar.indexOf(image) + 1;

Expand Down
67 changes: 1 addition & 66 deletions app/controllers/settings/apps/unsplash.js
@@ -1,51 +1,18 @@
import Controller from '@ember/controller';
import {alias, empty} from '@ember/object/computed';
import {alias} from '@ember/object/computed';
import {inject as injectService} from '@ember/service';
import {task} from 'ember-concurrency';

export default Controller.extend({
notifications: injectService(),
settings: injectService(),
config: injectService(),
unsplash: injectService(),

model: alias('settings.unsplash'),
testRequestDisabled: empty('model.applicationId'),

_triggerValidations() {
let isActive = this.get('model.isActive');
let applicationId = this.get('model.applicationId');

this.get('model.hasValidated').clear();

// api key field is hidden if set via config so don't validate in that case
if (!this.get('config.unsplashAPI.applicationId')) {
// CASE: application id is empty but unsplash is enabled
if (isActive && !applicationId) {
this.get('model.errors').add(
'isActive',
'You need to enter an Application ID before enabling it'
);

this.get('model.hasValidated').pushObject('isActive');
} else {
// run the validation for application id
this.get('model').validate();
}
}

this.get('model.hasValidated').pushObject('isActive');
},

save: task(function* () {
let unsplash = this.get('model');
let settings = this.get('settings');

// Don't save when we have errors and properties are not validated
if ((this.get('model.errors.isActive') || this.get('model.errors.applicationId'))) {
return;
}

try {
settings.set('unsplash', unsplash);
return yield settings.save();
Expand All @@ -57,45 +24,13 @@ export default Controller.extend({
}
}).drop(),

sendTestRequest: task(function* () {
let notifications = this.get('notifications');
let applicationId = this.get('model.applicationId');

try {
yield this.get('unsplash').sendTestRequest(applicationId);
} catch (error) {
notifications.showAPIError(error, {key: 'unsplash-test:send'});
return false;
}

// save the application id when it's valid
yield this.get('save').perform();
return true;
}).drop(),

actions: {
save() {
this.get('save').perform();
},

update(value) {
if (this.get('model.errors.isActive')) {
this.get('model.errors.isActive').clear();
}

this.set('model.isActive', value);
this._triggerValidations();
},

updateId(value) {
value = value ? value.toString().trim() : '';

if (this.get('model.errors.applicationId')) {
this.get('model.errors.applicationId').clear();
}

this.set('model.applicationId', value);
this._triggerValidations();
}
}
});
4 changes: 1 addition & 3 deletions app/mixins/validation-engine.js
Expand Up @@ -13,7 +13,6 @@ import SignupValidator from 'ghost-admin/validators/signup';
import SlackIntegrationValidator from 'ghost-admin/validators/slack-integration';
import SubscriberValidator from 'ghost-admin/validators/subscriber';
import TagSettingsValidator from 'ghost-admin/validators/tag-settings';
import UnsplashIntegrationValidator from 'ghost-admin/validators/unsplash-integration';
import UserValidator from 'ghost-admin/validators/user';
import ValidatorExtensions from 'ghost-admin/utils/validator-extensions';
import {A as emberA, isArray as isEmberArray} from '@ember/array';
Expand Down Expand Up @@ -47,8 +46,7 @@ export default Mixin.create({
slackIntegration: SlackIntegrationValidator,
subscriber: SubscriberValidator,
tag: TagSettingsValidator,
user: UserValidator,
unsplashIntegration: UnsplashIntegrationValidator
user: UserValidator
},

// This adds the Errors object to the validation engine, and shouldn't affect
Expand Down
8 changes: 1 addition & 7 deletions app/models/unsplash-integration.js
@@ -1,11 +1,5 @@
import EmberObject from '@ember/object';
import ValidationEngine from 'ghost-admin/mixins/validation-engine';

export default EmberObject.extend(ValidationEngine, {
// values entered here will act as defaults
applicationId: '',

validationType: 'unsplashIntegration',

export default EmberObject.extend({
isActive: false
});
3 changes: 1 addition & 2 deletions app/routes/settings/apps/unsplash.js
Expand Up @@ -22,8 +22,7 @@ export default AuthenticatedRoute.extend(styleBody, {
// - isActive: use as default but allow settings override
// - applicationId: total override, no field is shown if present
let unsplash = UnsplashObject.create({
isActive: this.get('config.unsplashAPI.isActive') || false,
applicationId: ''
isActive: true
});

settings.set('unsplash', unsplash);
Expand Down
11 changes: 0 additions & 11 deletions app/services/unsplash.js
Expand Up @@ -61,17 +61,6 @@ export default Service.extend({
}
},

sendTestRequest(testApplicationId) {
let url = `${API_URL}/photos/random`;
let headers = {};

headers.Authorization = `Client-ID ${testApplicationId}`;
headers['Accept-Version'] = API_VERSION;

return fetch(url, {headers})
.then((response) => this._checkStatus(response));
},

actions: {
updateSearch(term) {
if (term === this.get('searchTerm')) {
Expand Down
2 changes: 1 addition & 1 deletion app/templates/components/gh-image-uploader.hbs
Expand Up @@ -18,7 +18,7 @@
<div class="gh-btn gh-btn-outline" data-test-file-input-description><span>{{description}}</span></div>
{{/gh-file-input}}

{{#if (and allowUnsplash unsplash.isActive)}}
{{#if (and allowUnsplash settings.unsplash.isActive)}}
<div class="gh-image-uploader-unsplash" {{action (toggle "_showUnsplash" this)}}>
{{inline-svg "unsplash"}}
</div>
Expand Down
27 changes: 2 additions & 25 deletions app/templates/settings/apps/unsplash.hbs
Expand Up @@ -29,38 +29,15 @@
<div class="gh-setting-desc">Enable <a href="https://unsplash.com" target="_blank">Unsplash</a> image integration for your posts</div>
</div>
<div class="gh-setting-action">
{{#gh-form-group errors=model.errors hasValidated=model.hasValidated property="isActive" class="right"}}
<div class="form-group right">
<div class="for-checkbox">
<label for="isActive" class="checkbox">
{{one-way-checkbox model.isActive id="isActive" name="isActive" type="checkbox" update=(action "update") data-test-checkbox="unsplash"}}
<span class="input-toggle-component"></span>
</label>
</div>
{{gh-error-message errors=model.errors property="isActive"}}
{{/gh-form-group}}
</div>
</div>
</div>
{{#unless config.unsplashAPI.applicationId}}
<form class="app-config-form" id="unsplash-settings" novalidate="novalidate" {{action "save" on="submit"}}>
<div class="gh-setting">
<div class="gh-setting-content">

<div class="gh-setting-title">Unsplash API Key</div>
<div class="gh-setting-desc">Access Unsplash images from within the editor.</div>
<div class="gh-setting-content-extended">
{{#gh-form-group errors=model.errors hasValidated=model.hasValidated property="applicationId"}}
{{gh-input model.applicationId name="unsplash" update=(action "updateId") onenter=(action "save") focusOut=(action "validate" "applicationId" target=model) placeholder="0f387e82271755665bd49683e914856b1e34..." data-test-input="unsplash"}}
{{#unless model.errors.applicationId}}
<p>Set up a new Unsplash application <a href="https://unsplash.com/documentation#registering-your-application" target="_blank">here</a>, and grab the Application ID.</p>
{{else}}
{{gh-error-message errors=model.errors property="applicationId"}}
{{/unless}}
{{/gh-form-group}}
</div>
</div>
</div>
</form>
{{gh-task-button "Test Application ID" task=sendTestRequest runningText="Validating" successText="Valid Application ID" failureText="Invalid Application Id" class="gh-btn gh-btn-green gh-btn-icon" disabled=testRequestDisabled data-test-button="send-request"}}
{{/unless}}
</section>
</section>
23 changes: 0 additions & 23 deletions app/validators/unsplash-integration.js

This file was deleted.

8 changes: 7 additions & 1 deletion mirage/config/settings.js
Expand Up @@ -29,7 +29,13 @@ export default function mockSettings(server) {

newSettings.forEach((newSetting) => {
let {key} = newSetting;
db.settings.update({key}, newSetting);

if (db.settings.where({key}).length > 0) {
db.settings.update({key}, newSetting);
} else {
newSetting.type = newSetting.type || 'blog';
db.settings.insert(newSetting);
}
});

return {
Expand Down
10 changes: 0 additions & 10 deletions mirage/fixtures/settings.js
Expand Up @@ -192,15 +192,5 @@ export default [
created_by: 1,
updated_at: '2015-10-27T17:39:58.276Z',
updated_by: 1
},
{
id: 23,
created_at: '2017-08-11T06:38:10.000Z',
created_by: 1,
key: 'unsplash',
type: 'blog',
updated_at: '2017-08-11T08:00:14.000Z',
updated_by: 1,
value: '{"applicationId":"","isActive":false}'
}
];

0 comments on commit 2e12987

Please sign in to comment.