2018-06-15 23:03:24 +08:00
|
|
|
import RestModel from "discourse/models/rest";
|
|
|
|
import { default as computed } from "ember-addons/ember-computed-decorators";
|
2018-08-08 12:46:34 +08:00
|
|
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
2017-04-12 22:52:52 +08:00
|
|
|
|
2017-05-10 05:20:28 +08:00
|
|
|
const THEME_UPLOAD_VAR = 2;
|
|
|
|
|
2018-08-31 03:23:15 +08:00
|
|
|
export const THEMES = "themes";
|
|
|
|
export const COMPONENTS = "components";
|
2018-09-07 02:56:00 +08:00
|
|
|
const SETTINGS_TYPE_ID = 5;
|
2018-08-31 03:23:15 +08:00
|
|
|
|
2017-04-12 22:52:52 +08:00
|
|
|
const Theme = RestModel.extend({
|
2018-03-29 05:02:34 +08:00
|
|
|
FIELDS_IDS: [0, 1],
|
2019-01-12 00:54:23 +08:00
|
|
|
isActive: Ember.computed.or("default", "user_selectable"),
|
|
|
|
isPendingUpdates: Ember.computed.gt("remote_theme.commits_behind", 0),
|
|
|
|
hasEditedFields: Ember.computed.gt("editedFields.length", 0),
|
2018-03-29 05:02:34 +08:00
|
|
|
|
2018-06-15 23:03:24 +08:00
|
|
|
@computed("theme_fields")
|
2017-04-12 22:52:52 +08:00
|
|
|
themeFields(fields) {
|
|
|
|
if (!fields) {
|
2018-06-15 23:03:24 +08:00
|
|
|
this.set("theme_fields", []);
|
2017-04-12 22:52:52 +08:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
let hash = {};
|
2018-03-05 08:04:23 +08:00
|
|
|
fields.forEach(field => {
|
2018-06-15 23:03:24 +08:00
|
|
|
if (!field.type_id || this.get("FIELDS_IDS").includes(field.type_id)) {
|
2018-03-05 08:04:23 +08:00
|
|
|
hash[this.getKey(field)] = field;
|
|
|
|
}
|
|
|
|
});
|
2017-04-12 22:52:52 +08:00
|
|
|
return hash;
|
|
|
|
},
|
|
|
|
|
2019-01-10 18:06:01 +08:00
|
|
|
@computed("theme_fields", "theme_fields.[]")
|
2017-05-10 05:20:28 +08:00
|
|
|
uploads(fields) {
|
|
|
|
if (!fields) {
|
|
|
|
return [];
|
|
|
|
}
|
2018-06-15 23:03:24 +08:00
|
|
|
return fields.filter(
|
|
|
|
f => f.target === "common" && f.type_id === THEME_UPLOAD_VAR
|
|
|
|
);
|
2017-05-10 05:20:28 +08:00
|
|
|
},
|
|
|
|
|
2018-08-31 03:23:15 +08:00
|
|
|
@computed("theme_fields", "theme_fields.@each.error")
|
|
|
|
isBroken(fields) {
|
|
|
|
return (
|
|
|
|
fields && fields.some(field => field.error && field.error.length > 0)
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
2019-01-10 18:06:01 +08:00
|
|
|
@computed("theme_fields.[]")
|
2018-09-07 02:56:00 +08:00
|
|
|
editedFields(fields) {
|
|
|
|
return fields.filter(
|
2019-01-12 00:54:23 +08:00
|
|
|
field => !Ember.isBlank(field.value) && field.type_id !== SETTINGS_TYPE_ID
|
2018-09-07 02:56:00 +08:00
|
|
|
);
|
2018-08-31 03:23:15 +08:00
|
|
|
},
|
|
|
|
|
2018-09-08 21:24:11 +08:00
|
|
|
@computed("remote_theme.last_error_text")
|
|
|
|
remoteError(errorText) {
|
|
|
|
if (errorText && errorText.length > 0) {
|
|
|
|
return errorText;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-06-15 23:03:24 +08:00
|
|
|
getKey(field) {
|
2018-03-05 08:04:23 +08:00
|
|
|
return `${field.target} ${field.name}`;
|
2017-05-10 05:20:28 +08:00
|
|
|
},
|
|
|
|
|
2018-06-15 23:03:24 +08:00
|
|
|
hasEdited(target, name) {
|
2017-04-20 03:24:00 +08:00
|
|
|
if (name) {
|
2019-01-12 00:54:23 +08:00
|
|
|
return !Ember.isEmpty(this.getField(target, name));
|
2017-04-20 03:24:00 +08:00
|
|
|
} else {
|
|
|
|
let fields = this.get("theme_fields") || [];
|
2018-06-15 23:03:24 +08:00
|
|
|
return fields.any(
|
2019-01-12 00:54:23 +08:00
|
|
|
field => field.target === target && !Ember.isEmpty(field.value)
|
2018-06-15 23:03:24 +08:00
|
|
|
);
|
2017-04-20 03:24:00 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2017-04-20 04:46:28 +08:00
|
|
|
getError(target, name) {
|
|
|
|
let themeFields = this.get("themeFields");
|
2018-06-15 23:03:24 +08:00
|
|
|
let key = this.getKey({ target, name });
|
2017-04-20 04:46:28 +08:00
|
|
|
let field = themeFields[key];
|
|
|
|
return field ? field.error : "";
|
|
|
|
},
|
|
|
|
|
2017-04-12 22:52:52 +08:00
|
|
|
getField(target, name) {
|
|
|
|
let themeFields = this.get("themeFields");
|
2018-06-15 23:03:24 +08:00
|
|
|
let key = this.getKey({ target, name });
|
2017-04-12 22:52:52 +08:00
|
|
|
let field = themeFields[key];
|
|
|
|
return field ? field.value : "";
|
|
|
|
},
|
|
|
|
|
2017-05-10 05:20:28 +08:00
|
|
|
removeField(field) {
|
2017-04-12 22:52:52 +08:00
|
|
|
this.set("changed", true);
|
|
|
|
|
2017-05-10 05:20:28 +08:00
|
|
|
field.upload_id = null;
|
|
|
|
field.value = null;
|
|
|
|
|
|
|
|
return this.saveChanges("theme_fields");
|
|
|
|
},
|
|
|
|
|
|
|
|
setField(target, name, value, upload_id, type_id) {
|
|
|
|
this.set("changed", true);
|
2017-04-12 22:52:52 +08:00
|
|
|
let themeFields = this.get("themeFields");
|
2018-06-15 23:03:24 +08:00
|
|
|
let field = { name, target, value, upload_id, type_id };
|
2017-05-10 05:20:28 +08:00
|
|
|
|
|
|
|
// slow path for uploads and so on
|
|
|
|
if (type_id && type_id > 1) {
|
|
|
|
let fields = this.get("theme_fields");
|
2018-06-15 23:03:24 +08:00
|
|
|
let existing = fields.find(
|
|
|
|
f => f.target === target && f.name === name && f.type_id === type_id
|
|
|
|
);
|
2017-05-10 05:20:28 +08:00
|
|
|
if (existing) {
|
|
|
|
existing.value = value;
|
|
|
|
existing.upload_id = upload_id;
|
|
|
|
} else {
|
|
|
|
fields.push(field);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// fast path
|
2018-06-15 23:03:24 +08:00
|
|
|
let key = this.getKey({ target, name });
|
2017-05-10 05:20:28 +08:00
|
|
|
let existingField = themeFields[key];
|
|
|
|
if (!existingField) {
|
2017-04-12 22:52:52 +08:00
|
|
|
this.theme_fields.push(field);
|
|
|
|
themeFields[key] = field;
|
|
|
|
} else {
|
2017-05-10 05:20:28 +08:00
|
|
|
existingField.value = value;
|
2017-04-12 22:52:52 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2019-01-10 18:06:01 +08:00
|
|
|
@computed("childThemes.[]")
|
2017-04-12 22:52:52 +08:00
|
|
|
child_theme_ids(childThemes) {
|
|
|
|
if (childThemes) {
|
|
|
|
return childThemes.map(theme => Ember.get(theme, "id"));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
removeChildTheme(theme) {
|
|
|
|
const childThemes = this.get("childThemes");
|
|
|
|
childThemes.removeObject(theme);
|
|
|
|
return this.saveChanges("child_theme_ids");
|
|
|
|
},
|
|
|
|
|
2018-06-15 23:03:24 +08:00
|
|
|
addChildTheme(theme) {
|
2017-04-12 22:52:52 +08:00
|
|
|
let childThemes = this.get("childThemes");
|
2017-04-21 05:37:13 +08:00
|
|
|
if (!childThemes) {
|
|
|
|
childThemes = [];
|
2018-06-15 23:03:24 +08:00
|
|
|
this.set("childThemes", childThemes);
|
2017-04-21 05:37:13 +08:00
|
|
|
}
|
2017-04-12 22:52:52 +08:00
|
|
|
childThemes.removeObject(theme);
|
|
|
|
childThemes.pushObject(theme);
|
|
|
|
return this.saveChanges("child_theme_ids");
|
|
|
|
},
|
|
|
|
|
2018-06-15 23:03:24 +08:00
|
|
|
@computed("name", "default")
|
2017-04-12 22:52:52 +08:00
|
|
|
description: function(name, isDefault) {
|
|
|
|
if (isDefault) {
|
2018-06-15 23:03:24 +08:00
|
|
|
return I18n.t("admin.customize.theme.default_name", { name: name });
|
2017-04-12 22:52:52 +08:00
|
|
|
} else {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
checkForUpdates() {
|
2018-06-15 23:03:24 +08:00
|
|
|
return this.save({ remote_check: true }).then(() =>
|
|
|
|
this.set("changed", false)
|
|
|
|
);
|
2017-04-12 22:52:52 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
updateToLatest() {
|
2018-06-15 23:03:24 +08:00
|
|
|
return this.save({ remote_update: true }).then(() =>
|
|
|
|
this.set("changed", false)
|
|
|
|
);
|
2017-04-12 22:52:52 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
changed: false,
|
|
|
|
|
|
|
|
saveChanges() {
|
|
|
|
const hash = this.getProperties.apply(this, arguments);
|
2018-08-08 12:46:34 +08:00
|
|
|
return this.save(hash)
|
|
|
|
.finally(() => this.set("changed", false))
|
|
|
|
.catch(popupAjaxError);
|
2017-04-12 22:52:52 +08:00
|
|
|
},
|
|
|
|
|
2018-03-05 08:04:23 +08:00
|
|
|
saveSettings(name, value) {
|
|
|
|
const settings = {};
|
|
|
|
settings[name] = value;
|
|
|
|
return this.save({ settings });
|
2019-01-17 19:46:11 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
saveTranslation(name, value) {
|
|
|
|
return this.save({ translations: { [name]: value } });
|
2018-03-05 08:04:23 +08:00
|
|
|
}
|
2017-04-12 22:52:52 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
export default Theme;
|