mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Added new brand color publication setting (#1409)
no issue Reads new brand primary color setting and adds UI to modify/update it behind the dev flag
This commit is contained in:
parent
6a1edceded
commit
5a25f83685
4 changed files with 135 additions and 1 deletions
|
@ -8,6 +8,7 @@ import {
|
||||||
IMAGE_MIME_TYPES
|
IMAGE_MIME_TYPES
|
||||||
} from 'ghost-admin/components/gh-image-uploader';
|
} from 'ghost-admin/components/gh-image-uploader';
|
||||||
import {computed} from '@ember/object';
|
import {computed} from '@ember/object';
|
||||||
|
import {htmlSafe} from '@ember/string';
|
||||||
import {run} from '@ember/runloop';
|
import {run} from '@ember/runloop';
|
||||||
import {inject as service} from '@ember/service';
|
import {inject as service} from '@ember/service';
|
||||||
import {task} from 'ember-concurrency';
|
import {task} from 'ember-concurrency';
|
||||||
|
@ -34,7 +35,6 @@ export default Controller.extend({
|
||||||
iconMimeTypes: 'image/png,image/x-icon',
|
iconMimeTypes: 'image/png,image/x-icon',
|
||||||
imageExtensions: IMAGE_EXTENSIONS,
|
imageExtensions: IMAGE_EXTENSIONS,
|
||||||
imageMimeTypes: IMAGE_MIME_TYPES,
|
imageMimeTypes: IMAGE_MIME_TYPES,
|
||||||
|
|
||||||
_scratchFacebook: null,
|
_scratchFacebook: null,
|
||||||
_scratchTwitter: null,
|
_scratchTwitter: null,
|
||||||
|
|
||||||
|
@ -50,6 +50,19 @@ export default Controller.extend({
|
||||||
return `${blogUrl}/${publicHash}/rss`;
|
return `${blogUrl}/${publicHash}/rss`;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
backgroundStyle: computed('settings.brand.primaryColor', function () {
|
||||||
|
let color = this.get('settings.brand.primaryColor') || '#ffffff';
|
||||||
|
return htmlSafe(`background-color: ${color}`);
|
||||||
|
}),
|
||||||
|
|
||||||
|
brandColor: computed('settings.brand.primaryColor', function () {
|
||||||
|
let color = this.get('settings.brand.primaryColor');
|
||||||
|
if (color && color[0] === '#') {
|
||||||
|
return color.slice(1);
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
save() {
|
save() {
|
||||||
this.save.perform();
|
this.save.perform();
|
||||||
|
@ -257,6 +270,42 @@ export default Controller.extend({
|
||||||
this.get('settings.hasValidated').pushObject('twitter');
|
this.get('settings.hasValidated').pushObject('twitter');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
validateBrandColor() {
|
||||||
|
let newColor = this.get('brandColor');
|
||||||
|
let oldColor = this.get('settings.brand.primaryColor');
|
||||||
|
let errMessage = '';
|
||||||
|
|
||||||
|
// reset errors and validation
|
||||||
|
this.get('settings.errors').remove('brandColor');
|
||||||
|
this.get('settings.hasValidated').removeObject('brandColor');
|
||||||
|
|
||||||
|
if (newColor === '') {
|
||||||
|
// Clear out the brand color
|
||||||
|
this.set('settings.brand.primaryColor', '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// brandColor 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}$/)) {
|
||||||
|
this.set('settings.brand.primaryColor', '');
|
||||||
|
run.schedule('afterRender', this, function () {
|
||||||
|
this.set('settings.brand.primaryColor', newColor);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errMessage = 'The color should be in valid hex format';
|
||||||
|
this.get('settings.errors').add('brandColor', errMessage);
|
||||||
|
this.get('settings.hasValidated').pushObject('brandColor');
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ export default Model.extend(ValidationEngine, {
|
||||||
logo: attr('string'),
|
logo: attr('string'),
|
||||||
coverImage: attr('string'),
|
coverImage: attr('string'),
|
||||||
icon: attr('string'),
|
icon: attr('string'),
|
||||||
|
brand: attr('json-string'),
|
||||||
defaultLocale: attr('string'),
|
defaultLocale: attr('string'),
|
||||||
activeTimezone: attr('string', {defaultValue: 'Etc/UTC'}),
|
activeTimezone: attr('string', {defaultValue: 'Etc/UTC'}),
|
||||||
codeinjectionHead: attr('string'),
|
codeinjectionHead: attr('string'),
|
||||||
|
|
|
@ -796,3 +796,62 @@ p.theme-validation-details {
|
||||||
.blog-icon {
|
.blog-icon {
|
||||||
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ctitle%3ERectangle%3C/title%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%23E6EEF2' d='M0 0h24v24H0z'/%3E%3Cpath fill='%23D8E2E8' d='M0 0h12v12H0zM12 12h12v12H12z'/%3E%3C/g%3E%3C/svg%3E");
|
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ctitle%3ERectangle%3C/title%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath fill='%23E6EEF2' d='M0 0h24v24H0z'/%3E%3Cpath fill='%23D8E2E8' d='M0 0h12v12H0zM12 12h12v12H12z'/%3E%3C/g%3E%3C/svg%3E");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** CSS for accent color */
|
||||||
|
.input-color-form-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-color {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-color:after {
|
||||||
|
content: "#";
|
||||||
|
position: absolute;
|
||||||
|
top: 6px;
|
||||||
|
left: 40px;
|
||||||
|
color: var(--midlightgrey);
|
||||||
|
font-family: "Consolas", monaco, monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-color:focus {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-color input {
|
||||||
|
padding-left: 48px;
|
||||||
|
width: 110px;
|
||||||
|
height: 33px;
|
||||||
|
padding-right: 8px;
|
||||||
|
font-family: "Consolas", monaco, monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-color .color-box {
|
||||||
|
position: absolute;
|
||||||
|
top: 1px;
|
||||||
|
left: 1px;
|
||||||
|
width: 31px;
|
||||||
|
height: 31px;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: var(--lightgrey);
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-right: 1px solid var(--input-border);
|
||||||
|
box-shadow: inset 0 0 0 1px var(--white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-color input:focus + .color-box {
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
width: 30px;
|
||||||
|
height: 29px;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-bottom-left-radius: 3px;
|
||||||
|
}
|
|
@ -164,6 +164,31 @@
|
||||||
</div>
|
</div>
|
||||||
{{/gh-uploader}}
|
{{/gh-uploader}}
|
||||||
</div>
|
</div>
|
||||||
|
{{#if this.config.enableDeveloperExperiments}}
|
||||||
|
<div class="gh-setting" data-test-setting="brand-color">
|
||||||
|
<div class="gh-setting-content">
|
||||||
|
<div class="gh-setting-title">Accent Color</div>
|
||||||
|
<div class="gh-setting-desc">Primary color used in your publication theme</div>
|
||||||
|
</div>
|
||||||
|
<div class="gh-setting-action">
|
||||||
|
{{#gh-form-group errors=settings.errors hasValidated=settings.hasValidated property="brandColor" class="input-color-form-group"}}
|
||||||
|
<div class="input-color">
|
||||||
|
{{gh-text-input
|
||||||
|
name="brand-color"
|
||||||
|
placeholder="abcdef"
|
||||||
|
autocorrect="off"
|
||||||
|
maxlength="6"
|
||||||
|
focus-out=(action "validateBrandColor")
|
||||||
|
value=brandColor
|
||||||
|
data-test-brand-color-input=true
|
||||||
|
}}
|
||||||
|
<div class="color-box" style={{this.backgroundStyle}}></div>
|
||||||
|
</div>
|
||||||
|
{{gh-error-message errors=settings.errors property="brandColor" data-test-brandColor-error=true}}
|
||||||
|
{{/gh-form-group}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
<div class="gh-setting-last" data-test-setting="coverImage">
|
<div class="gh-setting-last" data-test-setting="coverImage">
|
||||||
{{#gh-uploader
|
{{#gh-uploader
|
||||||
extensions=this.imageExtensions
|
extensions=this.imageExtensions
|
||||||
|
|
Loading…
Add table
Reference in a new issue