mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-12 06:25:51 +03:00
c3b49b45cf
no issue - adds `settings` service that acts as a proxy to the singular settings model with methods to fetch and reload, also prevents accidentally loading only some settings types which has caused problems in the past - updates app boot, signin, and signup processes to fetch settings ensuring that any part of the app can grab settings synchronously if needed - removes `timeZone` service, it's no longer needed as we can grab `settings.activeTimezone` directly - replaces all store queries for the settings model with appropriate `settings` methods - refactors `apps/*` routes/controllers, they had become a little convoluted with the way they were dealing with settings and the new service helped to clean that up
95 lines
2.9 KiB
JavaScript
95 lines
2.9 KiB
JavaScript
import Ember from 'ember';
|
|
import Component from 'ember-component';
|
|
import {htmlSafe} from 'ember-string';
|
|
import computed, {alias, equal} from 'ember-computed';
|
|
import injectService from 'ember-service/inject';
|
|
import $ from 'jquery';
|
|
import {isBlank} from 'ember-utils';
|
|
|
|
// ember-cli-shims doesn't export these
|
|
const {Handlebars} = Ember;
|
|
|
|
export default Component.extend({
|
|
tagName: 'li',
|
|
classNames: ['gh-posts-list-item'],
|
|
classNameBindings: ['active'],
|
|
|
|
post: null,
|
|
active: false,
|
|
|
|
isFeatured: alias('post.featured'),
|
|
isPage: alias('post.page'),
|
|
isPublished: equal('post.status', 'published'),
|
|
isScheduled: equal('post.status', 'scheduled'),
|
|
|
|
ghostPaths: injectService(),
|
|
|
|
authorName: computed('post.author.name', 'post.author.email', function () {
|
|
return this.get('post.author.name') || this.get('post.author.email');
|
|
}),
|
|
|
|
authorAvatar: computed('post.author.image', function () {
|
|
return this.get('post.author.image') || `${this.get('ghostPaths.assetRoot')}/img/user-image.png`;
|
|
}),
|
|
|
|
authorAvatarBackground: computed('authorAvatar', function () {
|
|
let authorAvatar = this.get('authorAvatar');
|
|
let safeUrl = Handlebars.Utils.escapeExpression(authorAvatar);
|
|
return htmlSafe(`background-image: url(${safeUrl})`);
|
|
}),
|
|
|
|
// HACK: this is intentionally awful due to time constraints
|
|
// TODO: find a better way to get an excerpt! :)
|
|
subText: computed('post.{html,metaDescription}', function () {
|
|
let html = this.get('post.html');
|
|
let metaDescription = this.get('post.metaDescription');
|
|
let text;
|
|
|
|
if (!isBlank(metaDescription)) {
|
|
text = metaDescription;
|
|
} else {
|
|
let $html = $(`<div>${html}</div>`);
|
|
text = $html.text();
|
|
}
|
|
|
|
return htmlSafe(`${text.slice(0, 80)}…`);
|
|
}),
|
|
|
|
didReceiveAttrs() {
|
|
if (this.get('active')) {
|
|
this.scrollIntoView();
|
|
}
|
|
},
|
|
|
|
click() {
|
|
this.sendAction('onClick', this.get('post'));
|
|
},
|
|
|
|
doubleClick() {
|
|
this.sendAction('onDoubleClick', this.get('post'));
|
|
},
|
|
|
|
scrollIntoView() {
|
|
let element = this.$();
|
|
let offset = element.offset().top;
|
|
let elementHeight = element.height();
|
|
let container = $('.content-list');
|
|
let containerHeight = container.height();
|
|
let currentScroll = container.scrollTop();
|
|
let isBelowTop, isAboveBottom, isOnScreen;
|
|
|
|
isAboveBottom = offset < containerHeight;
|
|
isBelowTop = offset > elementHeight;
|
|
|
|
isOnScreen = isBelowTop && isAboveBottom;
|
|
|
|
if (!isOnScreen) {
|
|
// Scroll so that element is centered in container
|
|
// 40 is the amount of padding on the container
|
|
container.clearQueue().animate({
|
|
scrollTop: currentScroll + offset - 40 - containerHeight / 2
|
|
});
|
|
}
|
|
}
|
|
});
|