2018-01-11 17:16:42 +03:00
|
|
|
import $ from 'jquery';
|
2016-01-19 17:25:36 +03:00
|
|
|
import Ember from 'ember';
|
2017-08-22 10:53:26 +03:00
|
|
|
import EmberError from '@ember/error';
|
2017-10-30 12:38:01 +03:00
|
|
|
import Service, {inject as service} from '@ember/service';
|
2022-02-03 01:11:11 +03:00
|
|
|
import classic from 'ember-classic-decorator';
|
2022-01-21 22:25:47 +03:00
|
|
|
import {computed, set} from '@ember/object';
|
2022-11-03 14:14:36 +03:00
|
|
|
import {inject} from 'ghost-admin/decorators/inject';
|
2016-01-19 17:25:36 +03:00
|
|
|
|
2018-01-11 17:16:42 +03:00
|
|
|
export function feature(name, options = {}) {
|
|
|
|
let {user, onChange} = options;
|
2017-03-03 19:14:33 +03:00
|
|
|
let watchedProps = user ? [`accessibility.${name}`] : [`config.${name}`, `labs.${name}`];
|
|
|
|
|
|
|
|
return computed.apply(Ember, watchedProps.concat({
|
2016-01-19 17:25:36 +03:00
|
|
|
get() {
|
2018-01-18 18:36:01 +03:00
|
|
|
let enabled = false;
|
|
|
|
|
2017-03-03 19:14:33 +03:00
|
|
|
if (user) {
|
2018-01-18 18:36:01 +03:00
|
|
|
enabled = this.get(`accessibility.${name}`);
|
2023-05-25 16:00:31 +03:00
|
|
|
} else if (typeof this.get(`config.${name}`) === 'boolean') {
|
2018-01-18 18:36:01 +03:00
|
|
|
enabled = this.get(`config.${name}`);
|
|
|
|
} else {
|
|
|
|
enabled = this.get(`labs.${name}`) || false;
|
2017-03-03 19:14:33 +03:00
|
|
|
}
|
|
|
|
|
2018-01-18 18:36:01 +03:00
|
|
|
return enabled;
|
2016-01-19 17:25:36 +03:00
|
|
|
},
|
|
|
|
set(key, value) {
|
2018-01-18 18:36:01 +03:00
|
|
|
this.update(key, value, options);
|
2018-01-11 17:16:42 +03:00
|
|
|
|
|
|
|
if (onChange) {
|
|
|
|
// value must be passed here because the value isn't set until
|
|
|
|
// the setter function returns
|
|
|
|
this.get(onChange).bind(this)(value);
|
|
|
|
}
|
|
|
|
|
2016-05-05 17:03:09 +03:00
|
|
|
return value;
|
2016-01-19 17:25:36 +03:00
|
|
|
}
|
2017-03-03 19:14:33 +03:00
|
|
|
}));
|
2016-01-19 17:25:36 +03:00
|
|
|
}
|
|
|
|
|
2022-02-03 01:11:11 +03:00
|
|
|
@classic
|
|
|
|
export default class FeatureService extends Service {
|
2022-11-03 14:14:36 +03:00
|
|
|
@service lazyLoader;
|
|
|
|
@service notifications;
|
2022-02-03 22:04:43 +03:00
|
|
|
@service session;
|
|
|
|
@service settings;
|
2022-11-03 14:14:36 +03:00
|
|
|
@service store;
|
2022-02-03 01:11:11 +03:00
|
|
|
|
2022-11-03 14:14:36 +03:00
|
|
|
@inject config;
|
2016-01-19 17:25:36 +03:00
|
|
|
|
2022-01-31 16:05:20 +03:00
|
|
|
// features
|
2022-04-20 18:48:54 +03:00
|
|
|
@feature('emailAnalytics') emailAnalytics;
|
2022-01-31 16:05:20 +03:00
|
|
|
|
|
|
|
// user-specific flags
|
2022-02-03 01:11:11 +03:00
|
|
|
@feature('nightShift', {user: true, onChange: '_setAdminTheme'})
|
2022-02-14 15:15:32 +03:00
|
|
|
nightShift;
|
2022-02-03 01:11:11 +03:00
|
|
|
|
2023-01-26 17:42:11 +03:00
|
|
|
// user-specific referral invitation
|
|
|
|
@feature('referralInviteDismissed', {user: true}) referralInviteDismissed;
|
|
|
|
|
2022-01-31 16:05:20 +03:00
|
|
|
// labs flags
|
2022-04-20 18:48:54 +03:00
|
|
|
@feature('urlCache') urlCache;
|
2023-04-12 22:24:02 +03:00
|
|
|
@feature('lexicalMultiplayer') lexicalMultiplayer;
|
2022-10-10 10:27:45 +03:00
|
|
|
@feature('audienceFeedback') audienceFeedback;
|
2023-01-17 00:03:36 +03:00
|
|
|
@feature('webmentions') webmentions;
|
2023-02-28 10:07:32 +03:00
|
|
|
@feature('stripeAutomaticTax') stripeAutomaticTax;
|
2023-06-01 14:32:37 +03:00
|
|
|
@feature('emailCustomization') emailCustomization;
|
2023-03-20 23:31:58 +03:00
|
|
|
@feature('i18n') i18n;
|
2023-04-18 12:12:37 +03:00
|
|
|
@feature('announcementBar') announcementBar;
|
2023-05-09 17:27:36 +03:00
|
|
|
@feature('signupCard') signupCard;
|
2023-05-11 12:30:58 +03:00
|
|
|
@feature('collections') collections;
|
2023-06-23 14:22:01 +03:00
|
|
|
@feature('mailEvents') mailEvents;
|
2023-07-10 16:43:24 +03:00
|
|
|
@feature('collectionsCard') collectionsCard;
|
2023-07-25 12:52:52 +03:00
|
|
|
@feature('importMemberTier') importMemberTier;
|
2023-08-30 18:54:03 +03:00
|
|
|
@feature('lexicalIndicators') lexicalIndicators;
|
2023-11-20 16:30:15 +03:00
|
|
|
@feature('adminXDemo') adminXDemo;
|
2024-04-25 11:44:29 +03:00
|
|
|
@feature('ActivityPub') ActivityPub;
|
2024-06-05 19:59:30 +03:00
|
|
|
@feature('editorExcerpt') editorExcerpt;
|
2024-06-26 11:37:01 +03:00
|
|
|
@feature('contentVisibility') contentVisibility;
|
2024-09-12 08:49:22 +03:00
|
|
|
@feature('commentImprovements') commentImprovements;
|
2022-02-21 18:45:59 +03:00
|
|
|
|
2022-02-03 01:11:11 +03:00
|
|
|
_user = null;
|
|
|
|
|
|
|
|
@computed('settings.labs')
|
|
|
|
get labs() {
|
2022-10-07 16:23:21 +03:00
|
|
|
let labs = this.settings.labs;
|
2016-01-19 17:25:36 +03:00
|
|
|
|
|
|
|
try {
|
|
|
|
return JSON.parse(labs) || {};
|
|
|
|
} catch (e) {
|
|
|
|
return {};
|
|
|
|
}
|
2022-02-03 01:11:11 +03:00
|
|
|
}
|
2016-05-05 17:03:09 +03:00
|
|
|
|
2022-02-03 01:11:11 +03:00
|
|
|
@computed('_user.accessibility')
|
|
|
|
get accessibility() {
|
2017-03-03 19:14:33 +03:00
|
|
|
let accessibility = this.get('_user.accessibility');
|
|
|
|
|
|
|
|
try {
|
|
|
|
return JSON.parse(accessibility) || {};
|
|
|
|
} catch (e) {
|
|
|
|
return {};
|
|
|
|
}
|
2022-02-03 01:11:11 +03:00
|
|
|
}
|
2017-03-03 19:14:33 +03:00
|
|
|
|
2016-05-05 17:03:09 +03:00
|
|
|
fetch() {
|
2021-07-08 16:37:31 +03:00
|
|
|
return this.settings.fetch().then(() => {
|
|
|
|
this.set('_user', this.session.user);
|
2018-01-11 17:16:42 +03:00
|
|
|
return this._setAdminTheme().then(() => true);
|
2016-05-05 17:03:09 +03:00
|
|
|
});
|
2022-02-03 01:11:11 +03:00
|
|
|
}
|
2016-01-19 17:25:36 +03:00
|
|
|
|
2018-01-18 18:36:01 +03:00
|
|
|
update(key, value, options = {}) {
|
|
|
|
let serviceProperty = options.user ? 'accessibility' : 'labs';
|
|
|
|
let model = this.get(options.user ? '_user' : 'settings');
|
2017-03-03 19:14:33 +03:00
|
|
|
let featureObject = this.get(serviceProperty);
|
|
|
|
|
|
|
|
// set the new key value for either the labs property or the accessibility property
|
|
|
|
set(featureObject, key, value);
|
2016-05-05 17:03:09 +03:00
|
|
|
|
2021-10-12 17:33:03 +03:00
|
|
|
if (options.requires && value === true) {
|
|
|
|
options.requires.forEach((flag) => {
|
|
|
|
set(featureObject, flag, true);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-03-03 19:14:33 +03:00
|
|
|
// update the 'labs' or 'accessibility' key of the model
|
|
|
|
model.set(serviceProperty, JSON.stringify(featureObject));
|
2016-05-05 17:03:09 +03:00
|
|
|
|
2017-03-03 19:14:33 +03:00
|
|
|
return model.save().then(() => {
|
2016-05-05 17:03:09 +03:00
|
|
|
// return the labs key value that we get from the server
|
2017-03-03 19:14:33 +03:00
|
|
|
this.notifyPropertyChange(serviceProperty);
|
|
|
|
return this.get(`${serviceProperty}.${key}`);
|
2016-06-30 17:45:02 +03:00
|
|
|
}).catch((error) => {
|
2017-03-03 19:14:33 +03:00
|
|
|
model.rollbackAttributes();
|
|
|
|
this.notifyPropertyChange(serviceProperty);
|
2016-05-05 17:03:09 +03:00
|
|
|
|
|
|
|
// we'll always have an errors object unless we hit a
|
|
|
|
// validation error
|
2016-06-30 17:45:02 +03:00
|
|
|
if (!error) {
|
2018-01-18 18:36:01 +03:00
|
|
|
throw new EmberError(`Validation of the feature service ${options.user ? 'user' : 'settings'} model failed when updating ${serviceProperty}.`);
|
2016-05-05 17:03:09 +03:00
|
|
|
}
|
|
|
|
|
2019-03-06 16:53:54 +03:00
|
|
|
this.notifications.showAPIError(error);
|
2016-05-05 17:03:09 +03:00
|
|
|
|
2017-03-03 19:14:33 +03:00
|
|
|
return this.get(`${serviceProperty}.${key}`);
|
2016-01-19 17:25:36 +03:00
|
|
|
});
|
2022-02-03 01:11:11 +03:00
|
|
|
}
|
2018-01-11 17:16:42 +03:00
|
|
|
|
|
|
|
_setAdminTheme(enabled) {
|
2018-03-09 12:34:43 +03:00
|
|
|
let nightShift = enabled;
|
|
|
|
|
|
|
|
if (typeof nightShift === 'undefined') {
|
2019-03-06 16:53:54 +03:00
|
|
|
nightShift = enabled || this.nightShift;
|
2018-03-09 12:34:43 +03:00
|
|
|
}
|
2018-01-11 17:16:42 +03:00
|
|
|
|
2019-03-06 16:53:54 +03:00
|
|
|
return this.lazyLoader.loadStyle('dark', 'assets/ghost-dark.css', true).then(() => {
|
2018-01-11 17:16:42 +03:00
|
|
|
$('link[title=dark]').prop('disabled', !nightShift);
|
2019-06-18 14:54:37 +03:00
|
|
|
}).catch(() => {
|
|
|
|
//TODO: Also disable toggle from settings and Labs hover
|
|
|
|
$('link[title=dark]').prop('disabled', true);
|
2018-01-11 17:16:42 +03:00
|
|
|
});
|
2016-01-19 17:25:36 +03:00
|
|
|
}
|
2022-02-03 01:11:11 +03:00
|
|
|
}
|