209 lines
6.4 KiB
JavaScript
209 lines
6.4 KiB
JavaScript
import Component from '@ember/component';
|
|
import Ember from 'ember';
|
|
import {action, computed} from '@ember/object';
|
|
import {htmlSafe} from '@ember/template';
|
|
import {or} from '@ember/object/computed';
|
|
import {run} from '@ember/runloop';
|
|
import {inject as service} from '@ember/service';
|
|
import {task, timeout} from 'ember-concurrency';
|
|
|
|
const {Handlebars} = Ember;
|
|
|
|
export default Component.extend({
|
|
feature: service(),
|
|
config: service(),
|
|
settings: service(),
|
|
|
|
tag: null,
|
|
scratchTag: null,
|
|
|
|
// Allowed actions
|
|
setProperty: () => {},
|
|
|
|
twitterTitle: or('scratchTag.twitterTitle', 'seoTitle'),
|
|
twitterDescription: or('scratchTag.twitterDescription', 'seoDescription', 'settings.metaDescription', ''),
|
|
twitterImage: or('tag.twitterImage', 'tag.featureImage'),
|
|
|
|
facebookTitle: or('scratchTag.ogTitle', 'seoTitle'),
|
|
facebookDescription: or('scratchTag.ogDescription', 'seoDescription', 'settings.metaDescription', ''),
|
|
facebookImage: or('tag.ogImage', 'tag.featureImage'),
|
|
|
|
accentColor: computed('tag.accentColor', function () {
|
|
let color = this.get('tag.accentColor');
|
|
if (color && color[0] === '#') {
|
|
return color.slice(1);
|
|
}
|
|
return color;
|
|
}),
|
|
|
|
accentColorPickerValue: computed('tag.accentColor', function () {
|
|
return this.tag.get('accentColor') || '#ffffff';
|
|
}),
|
|
|
|
accentColorBgStyle: computed('accentColorPickerValue', function () {
|
|
return htmlSafe(`background-color: ${this.accentColorPickerValue}`);
|
|
}),
|
|
|
|
title: computed('tag.isNew', function () {
|
|
if (this.get('tag.isNew')) {
|
|
return 'New tag';
|
|
} else {
|
|
return 'Tag settings';
|
|
}
|
|
}),
|
|
|
|
seoTitle: computed('scratchTag.{name,metaTitle}', function () {
|
|
const settingsTitle = this.get('settings.title') || '';
|
|
const tagName = settingsTitle ? `${this.scratchTag.name} - ${settingsTitle}` : this.scratchTag.name;
|
|
let metaTitle = this.scratchTag.metaTitle || tagName;
|
|
|
|
if (metaTitle && metaTitle.length > 70) {
|
|
metaTitle = metaTitle.substring(0, 70).trim();
|
|
metaTitle = Handlebars.Utils.escapeExpression(metaTitle);
|
|
metaTitle = htmlSafe(`${metaTitle}…`);
|
|
}
|
|
|
|
return metaTitle;
|
|
}),
|
|
|
|
seoURL: computed('scratchTag.{canonicalUrl,slug}', function () {
|
|
let blogUrl = this.get('config.blogUrl');
|
|
let seoSlug = this.scratchTag.slug || '';
|
|
|
|
let seoURL = this.scratchTag.canonicalUrl || `${blogUrl}/tag/${seoSlug}`;
|
|
|
|
// only append a slash to the URL if the slug exists
|
|
|
|
if (!seoURL.endsWith('/')) {
|
|
seoURL += '/';
|
|
}
|
|
|
|
if (seoURL.length > 70) {
|
|
seoURL = seoURL.substring(0, 70).trim();
|
|
seoURL = Handlebars.Utils.escapeExpression(seoURL);
|
|
seoURL = htmlSafe(`${seoURL}…`);
|
|
}
|
|
|
|
return seoURL;
|
|
}),
|
|
|
|
seoDescription: computed('scratchTag.{description,metaDescription}', function () {
|
|
let metaDescription = this.scratchTag.metaDescription || '';
|
|
|
|
metaDescription = metaDescription.length > 0 ? metaDescription : this.scratchTag.description;
|
|
|
|
if (metaDescription && metaDescription.length > 156) {
|
|
metaDescription = metaDescription.substring(0, 156).trim();
|
|
metaDescription = Handlebars.Utils.escapeExpression(metaDescription);
|
|
metaDescription = htmlSafe(`${metaDescription}…`);
|
|
}
|
|
|
|
return metaDescription;
|
|
}),
|
|
|
|
actions: {
|
|
setProperty(property, value) {
|
|
this.setProperty(property, value);
|
|
},
|
|
|
|
setTwitterImage(image) {
|
|
this.setProperty('twitterImage', image);
|
|
},
|
|
|
|
clearTwitterImage() {
|
|
this.setProperty('twitterImage', '');
|
|
},
|
|
|
|
setOgImage(image) {
|
|
this.setProperty('ogImage', image);
|
|
},
|
|
|
|
clearOgImage() {
|
|
this.setProperty('ogImage', '');
|
|
},
|
|
|
|
setCoverImage(image) {
|
|
this.setProperty('featureImage', image);
|
|
},
|
|
|
|
clearCoverImage() {
|
|
this.setProperty('featureImage', '');
|
|
},
|
|
|
|
validateCanonicalUrl() {
|
|
let newUrl = this.get('scratchTag.canonicalUrl');
|
|
let oldUrl = this.get('tag.canonicalUrl');
|
|
let errMessage = '';
|
|
|
|
this.get('tag.errors').remove('canonicalUrl');
|
|
this.get('tag.hasValidated').removeObject('canonicalUrl');
|
|
|
|
if (newUrl === '') {
|
|
this.setProperty('canonicalUrl', '');
|
|
return;
|
|
}
|
|
|
|
if (!newUrl) {
|
|
newUrl = oldUrl;
|
|
}
|
|
|
|
try {
|
|
new URL(newUrl);
|
|
this.setProperty('canonicalUrl', '');
|
|
run.schedule('afterRender', this, function () {
|
|
this.setProperty('canonicalUrl', newUrl);
|
|
});
|
|
} catch (err) {
|
|
errMessage = 'The url should be a valid url';
|
|
this.get('tag.errors').add('canonicalUrl', errMessage);
|
|
this.get('tag.hasValidated').pushObject('canonicalUrl');
|
|
}
|
|
}
|
|
},
|
|
|
|
updateAccentColor: action(async function (event) {
|
|
let newColor = event.target.value;
|
|
const oldColor = this.tag.get('accentColor');
|
|
|
|
// reset errors and validation
|
|
this.tag.errors.remove('accentColor');
|
|
this.tag.hasValidated.removeObject('accentColor');
|
|
|
|
if (newColor === '') {
|
|
if (newColor === oldColor) {
|
|
return;
|
|
}
|
|
|
|
// clear out the accent color
|
|
this.tag.set('accentColor', '');
|
|
return;
|
|
}
|
|
|
|
// accentColor will be null unless the user has input something
|
|
if (!newColor) {
|
|
newColor = oldColor;
|
|
}
|
|
|
|
if (newColor[0] !== '#') {
|
|
newColor = `#${newColor}`;
|
|
}
|
|
|
|
if (newColor.match(/#[0-9A-Fa-f]{6}$/)) {
|
|
if (newColor === oldColor) {
|
|
return;
|
|
}
|
|
|
|
this.tag.set('accentColor', newColor);
|
|
this.scratchTag.set('accentColor', newColor);
|
|
} else {
|
|
this.tag.errors.add('accentColor', 'The colour should be in valid hex format');
|
|
this.tag.hasValidated.pushObject('accentColor');
|
|
}
|
|
}),
|
|
|
|
debounceUpdateAccentColor: task(function*(event) {
|
|
yield timeout(10);
|
|
this.updateAccentColor(event);
|
|
})
|
|
});
|