diff --git a/Gemfile b/Gemfile
index 9d85677d9d8..5673b004978 100644
--- a/Gemfile
+++ b/Gemfile
@@ -49,7 +49,7 @@ gem 'onebox', '1.8.86'
gem 'http_accept_language', '~>2.0.5', require: false
gem 'ember-rails', '0.18.5'
-gem 'discourse-ember-source', '~> 3.7.0'
+gem 'discourse-ember-source', '~> 3.8.0'
gem 'ember-handlebars-template', '0.8.0'
gem 'barber'
diff --git a/Gemfile.lock b/Gemfile.lock
index ba914300e7f..8f7e311e88c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -108,7 +108,7 @@ GEM
terminal-table (~> 1)
debug_inspector (0.0.3)
diff-lcs (1.3)
- discourse-ember-source (3.7.0.2)
+ discourse-ember-source (3.8.0.1)
discourse_image_optim (0.26.2)
exifr (~> 1.2, >= 1.2.2)
fspath (~> 3.0)
@@ -472,7 +472,7 @@ DEPENDENCIES
colored2
cppjieba_rb
danger
- discourse-ember-source (~> 3.7.0)
+ discourse-ember-source (~> 3.8.0)
discourse_image_optim
email_reply_trimmer (~> 0.1)
ember-handlebars-template (= 0.8.0)
diff --git a/app/assets/javascripts/admin/components/resumable-upload.js.es6 b/app/assets/javascripts/admin/components/resumable-upload.js.es6
index e462d9e32c4..c097a713dc9 100644
--- a/app/assets/javascripts/admin/components/resumable-upload.js.es6
+++ b/app/assets/javascripts/admin/components/resumable-upload.js.es6
@@ -1,5 +1,6 @@
import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
+import computed from "ember-addons/ember-computed-decorators";
/*global Resumable:true */
@@ -27,18 +28,19 @@ export default Ember.Component.extend(
rerenderTriggers: ["isUploading", "progress"],
- translatedTitle: function() {
- const title = this.get("title");
- return title ? I18n.t(title) : this.get("text");
- }.property("title", "text"),
+ @computed("title", "text")
+ translatedTitle(title, text) {
+ return title ? I18n.t(title) : text;
+ },
- text: function() {
- if (this.get("isUploading")) {
- return this.get("progress") + " %";
+ @computed("isUploading", "progress")
+ text(isUploading, progress) {
+ if (isUploading) {
+ return progress + " %";
} else {
return this.get("uploadText");
}
- }.property("isUploading", "progress"),
+ },
buildBuffer(buffer) {
const icon = this.get("isUploading") ? "times" : "upload";
diff --git a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6
index 5bf29b07883..d7e80054325 100644
--- a/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-badges-show.js.es6
@@ -1,6 +1,7 @@
import { popupAjaxError } from "discourse/lib/ajax-error";
import { bufferedProperty } from "discourse/mixins/buffered-content";
import { propertyNotEqual } from "discourse/lib/computed";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend(bufferedProperty("model"), {
adminBadges: Ember.inject.controller(),
@@ -17,14 +18,13 @@ export default Ember.Controller.extend(bufferedProperty("model"), {
readOnly: Ember.computed.alias("buffered.system"),
showDisplayName: propertyNotEqual("name", "displayName"),
- hasQuery: function() {
- const bQuery = this.get("buffered.query");
- if (bQuery) {
- return bQuery.trim().length > 0;
+ @computed("model.query", "buffered.query")
+ hasQuery(modelQuery, bufferedQuery) {
+ if (bufferedQuery) {
+ return bufferedQuery.trim().length > 0;
}
- const mQuery = this.get("model.query");
- return mQuery && mQuery.trim().length > 0;
- }.property("model.query", "buffered.query"),
+ return modelQuery && modelQuery.trim().length > 0;
+ },
_resetSaving: function() {
this.set("saving", false);
diff --git a/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6 b/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6
index 5a20a94cbfb..3fafd28e557 100644
--- a/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-customize-email-templates-edit.js.es6
@@ -1,17 +1,18 @@
import { popupAjaxError } from "discourse/lib/ajax-error";
import { bufferedProperty } from "discourse/mixins/buffered-content";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend(bufferedProperty("emailTemplate"), {
saved: false,
- hasMultipleSubjects: function() {
- const buffered = this.get("buffered");
+ @computed("buffered")
+ hasMultipleSubjects(buffered) {
if (buffered.getProperties("subject")["subject"]) {
return false;
} else {
return buffered.getProperties("id")["id"];
}
- }.property("buffered"),
+ },
actions: {
saveChanges() {
diff --git a/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6 b/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
index 16ed12e987c..9a596ad70f8 100644
--- a/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-logs-staff-action-logs.js.es6
@@ -1,6 +1,7 @@
import { exportEntity } from "discourse/lib/export-csv";
import { outputExportResult } from "discourse/lib/export-result";
import StaffActionLog from "admin/models/staff-action-log";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend({
loading: false,
@@ -20,14 +21,14 @@ export default Ember.Controller.extend({
}
}.observes("filterActionId"),
- actionFilter: function() {
- var name = this.get("filters.action_name");
+ @computed("filters.action_name")
+ actionFilter(name) {
if (name) {
return I18n.t("admin.logs.staff_actions.actions." + name);
} else {
return null;
}
- }.property("filters.action_name"),
+ },
showInstructions: Ember.computed.gt("model.length", 0),
diff --git a/app/assets/javascripts/admin/controllers/admin-plugins.js.es6 b/app/assets/javascripts/admin/controllers/admin-plugins.js.es6
index 5e91ad297da..2e34bfc7f79 100644
--- a/app/assets/javascripts/admin/controllers/admin-plugins.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-plugins.js.es6
@@ -1,4 +1,7 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Controller.extend({
+ @computed
adminRoutes: function() {
return this.get("model")
.map(p => {
@@ -7,7 +10,8 @@ export default Ember.Controller.extend({
}
})
.compact();
- }.property(),
+ },
+
actions: {
clearFilter() {
this.setProperties({ filter: "", onlyOverridden: false });
diff --git a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6 b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6
index 06cec9f53d8..06832ca0b60 100644
--- a/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-user-badges.js.es6
@@ -1,5 +1,6 @@
import GrantBadgeController from "discourse/mixins/grant-badge-controller";
import { popupAjaxError } from "discourse/lib/ajax-error";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend(GrantBadgeController, {
adminUser: Ember.inject.controller(),
@@ -10,7 +11,8 @@ export default Ember.Controller.extend(GrantBadgeController, {
sortedBadges: Ember.computed.sort("model", "badgeSortOrder"),
badgeSortOrder: ["granted_at:desc"],
- groupedBadges: function() {
+ @computed("model", "model.[]", "model.expandedBadges.[]")
+ groupedBadges() {
const allBadges = this.get("model");
var grouped = _.groupBy(allBadges, badge => badge.badge_id);
@@ -46,7 +48,7 @@ export default Ember.Controller.extend(GrantBadgeController, {
.sortBy(group => group.granted_at)
.reverse()
.value();
- }.property("model", "model.[]", "model.expandedBadges.[]"),
+ },
actions: {
expandGroup: function(userBadge) {
diff --git a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6 b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
index b5b0c5b08ae..f23fa949579 100644
--- a/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
+++ b/app/assets/javascripts/admin/controllers/admin-users-list-show.js.es6
@@ -2,6 +2,7 @@ import debounce from "discourse/lib/debounce";
import { i18n } from "discourse/lib/computed";
import AdminUser from "admin/models/admin-user";
import CanCheckEmails from "discourse/mixins/can-check-emails";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend(CanCheckEmails, {
model: null,
@@ -14,9 +15,10 @@ export default Ember.Controller.extend(CanCheckEmails, {
selectAll: false,
searchHint: i18n("search_hint"),
- title: function() {
- return I18n.t("admin.users.titles." + this.get("query"));
- }.property("query"),
+ @computed("query")
+ title(query) {
+ return I18n.t("admin.users.titles." + query);
+ },
_filterUsers: debounce(function() {
this._refreshUsers();
diff --git a/app/assets/javascripts/admin/mixins/setting-object.js.es6 b/app/assets/javascripts/admin/mixins/setting-object.js.es6
index 48c9528af78..ce3a217a98a 100644
--- a/app/assets/javascripts/admin/mixins/setting-object.js.es6
+++ b/app/assets/javascripts/admin/mixins/setting-object.js.es6
@@ -1,19 +1,20 @@
-export default Ember.Mixin.create({
- overridden: function() {
- let val = this.get("value"),
- defaultVal = this.get("default");
+import computed from "ember-addons/ember-computed-decorators";
+export default Ember.Mixin.create({
+ @computed("value", "default")
+ overridden(val, defaultVal) {
if (val === null) val = "";
if (defaultVal === null) defaultVal = "";
return val.toString() !== defaultVal.toString();
- }.property("value", "default"),
+ },
- validValues: function() {
+ @computed("valid_values")
+ validValues(validValues) {
const vals = [],
translateNames = this.get("translate_names");
- this.get("valid_values").forEach(v => {
+ validValues.forEach(v => {
if (v.name && v.name.length > 0 && translateNames) {
vals.addObject({ name: I18n.t(v.name), value: v.value });
} else {
@@ -21,12 +22,12 @@ export default Ember.Mixin.create({
}
});
return vals;
- }.property("valid_values"),
+ },
- allowsNone: function() {
- const validValues = this.get("valid_values");
+ @computed("valid_values")
+ allowsNone(validValues) {
if (validValues && validValues.indexOf("") >= 0) {
return "admin.settings.none";
}
- }.property("valid_values")
+ }
});
diff --git a/app/assets/javascripts/admin/models/admin-user.js.es6 b/app/assets/javascripts/admin/models/admin-user.js.es6
index bc1cba2f411..64c11cb108f 100644
--- a/app/assets/javascripts/admin/models/admin-user.js.es6
+++ b/app/assets/javascripts/admin/models/admin-user.js.es6
@@ -293,17 +293,19 @@ const AdminUser = Discourse.User.extend({
});
},
- canLockTrustLevel: function() {
- return this.get("trust_level") < 4;
- }.property("trust_level"),
+ @computed("trust_level")
+ canLockTrustLevel(trustLevel) {
+ return trustLevel < 4;
+ },
canSuspend: Ember.computed.not("staff"),
- suspendDuration: function() {
- const suspended_at = moment(this.suspended_at),
- suspended_till = moment(this.suspended_till);
- return suspended_at.format("L") + " - " + suspended_till.format("L");
- }.property("suspended_till", "suspended_at"),
+ @computed("suspended_till", "suspended_at")
+ suspendDuration(suspendedTill, suspendedAt) {
+ suspendedAt = moment(suspendedAt);
+ suspendedTill = moment(suspendedTill);
+ return suspendedAt.format("L") + " - " + suspendedTill.format("L");
+ },
suspend(data) {
return ajax(`/admin/users/${this.id}/suspend`, {
diff --git a/app/assets/javascripts/admin/models/color-scheme.js.es6 b/app/assets/javascripts/admin/models/color-scheme.js.es6
index e7fbe31f235..1e2d10869eb 100644
--- a/app/assets/javascripts/admin/models/color-scheme.js.es6
+++ b/app/assets/javascripts/admin/models/color-scheme.js.es6
@@ -1,5 +1,6 @@
import { ajax } from "discourse/lib/ajax";
import ColorSchemeColor from "admin/models/color-scheme-color";
+import computed from "ember-addons/ember-computed-decorators";
const ColorScheme = Discourse.Model.extend(Ember.Copyable, {
init: function() {
@@ -7,9 +8,10 @@ const ColorScheme = Discourse.Model.extend(Ember.Copyable, {
this.startTrackingChanges();
},
- description: function() {
+ @computed
+ description() {
return "" + this.name;
- }.property(),
+ },
startTrackingChanges: function() {
this.set("originals", {
@@ -44,7 +46,8 @@ const ColorScheme = Discourse.Model.extend(Ember.Copyable, {
return newScheme;
},
- changed: function() {
+ @computed("name", "colors.@each.changed", "saving")
+ changed() {
if (!this.originals) return false;
if (this.originals["name"] !== this.get("name")) return true;
if (
@@ -54,24 +57,23 @@ const ColorScheme = Discourse.Model.extend(Ember.Copyable, {
)
return true;
return false;
- }.property("name", "colors.@each.changed", "saving"),
+ },
- disableSave: function() {
+ @computed("changed")
+ disableSave(changed) {
if (this.get("theme_id")) {
return false;
}
return (
- !this.get("changed") ||
+ !changed ||
this.get("saving") ||
_.any(this.get("colors"), function(c) {
return !c.get("valid");
})
);
- }.property("changed"),
+ },
- newRecord: function() {
- return !this.get("id");
- }.property("id"),
+ newRecord: Ember.computed.not("id"),
save: function(opts) {
if (this.get("is_base") || this.get("disableSave")) return;
diff --git a/app/assets/javascripts/admin/models/report.js.es6 b/app/assets/javascripts/admin/models/report.js.es6
index aff881dd2d9..19a1579e5db 100644
--- a/app/assets/javascripts/admin/models/report.js.es6
+++ b/app/assets/javascripts/admin/models/report.js.es6
@@ -76,25 +76,35 @@ const Report = Discourse.Model.extend({
}
},
- todayCount: function() {
+ @computed("data", "average")
+ todayCount() {
return this.valueAt(0);
- }.property("data", "average"),
- yesterdayCount: function() {
- return this.valueAt(1);
- }.property("data", "average"),
- sevenDaysAgoCount: function() {
- return this.valueAt(7);
- }.property("data", "average"),
- thirtyDaysAgoCount: function() {
- return this.valueAt(30);
- }.property("data", "average"),
+ },
- lastSevenDaysCount: function() {
+ @computed("data", "average")
+ yesterdayCount() {
+ return this.valueAt(1);
+ },
+
+ @computed("data", "average")
+ sevenDaysAgoCount() {
+ return this.valueAt(7);
+ },
+
+ @computed("data", "average")
+ thirtyDaysAgoCount() {
+ return this.valueAt(30);
+ },
+
+ @computed("data", "average")
+ lastSevenDaysCount() {
return this.averageCount(7, this.valueFor(1, 7));
- }.property("data", "average"),
- lastThirtyDaysCount: function() {
+ },
+
+ @computed("data", "average")
+ lastThirtyDaysCount() {
return this.averageCount(30, this.valueFor(1, 30));
- }.property("data", "average"),
+ },
averageCount(count, value) {
return this.get("average") ? value / count : value;
diff --git a/app/assets/javascripts/admin/models/screened-email.js.es6 b/app/assets/javascripts/admin/models/screened-email.js.es6
index 1f1590baa00..23b4ec28c79 100644
--- a/app/assets/javascripts/admin/models/screened-email.js.es6
+++ b/app/assets/javascripts/admin/models/screened-email.js.es6
@@ -1,8 +1,11 @@
import { ajax } from "discourse/lib/ajax";
+import computed from "ember-addons/ember-computed-decorators";
+
const ScreenedEmail = Discourse.Model.extend({
- actionName: function() {
- return I18n.t("admin.logs.screened_actions." + this.get("action"));
- }.property("action"),
+ @computed("action")
+ actionName(action) {
+ return I18n.t("admin.logs.screened_actions." + action);
+ },
clearBlock: function() {
return ajax("/admin/logs/screened_emails/" + this.get("id"), {
diff --git a/app/assets/javascripts/admin/models/screened-url.js.es6 b/app/assets/javascripts/admin/models/screened-url.js.es6
index 06dc94f7d44..b899c619623 100644
--- a/app/assets/javascripts/admin/models/screened-url.js.es6
+++ b/app/assets/javascripts/admin/models/screened-url.js.es6
@@ -1,8 +1,11 @@
import { ajax } from "discourse/lib/ajax";
+import computed from "ember-addons/ember-computed-decorators";
+
const ScreenedUrl = Discourse.Model.extend({
- actionName: function() {
- return I18n.t("admin.logs.screened_actions." + this.get("action"));
- }.property("action")
+ @computed("action")
+ actionName(action) {
+ return I18n.t("admin.logs.screened_actions." + action);
+ }
});
ScreenedUrl.reopenClass({
diff --git a/app/assets/javascripts/admin/models/tl3-requirements.js.es6 b/app/assets/javascripts/admin/models/tl3-requirements.js.es6
index 2b49e660919..c30bc0404d5 100644
--- a/app/assets/javascripts/admin/models/tl3-requirements.js.es6
+++ b/app/assets/javascripts/admin/models/tl3-requirements.js.es6
@@ -11,36 +11,7 @@ export default Discourse.Model.extend({
return Math.round((minDaysVisited * 100) / timePeriod);
},
- met: function() {
- return {
- days_visited: this.get("days_visited") >= this.get("min_days_visited"),
- topics_replied_to:
- this.get("num_topics_replied_to") >= this.get("min_topics_replied_to"),
- topics_viewed: this.get("topics_viewed") >= this.get("min_topics_viewed"),
- posts_read: this.get("posts_read") >= this.get("min_posts_read"),
- topics_viewed_all_time:
- this.get("topics_viewed_all_time") >=
- this.get("min_topics_viewed_all_time"),
- posts_read_all_time:
- this.get("posts_read_all_time") >= this.get("min_posts_read_all_time"),
- flagged_posts:
- this.get("num_flagged_posts") <= this.get("max_flagged_posts"),
- flagged_by_users:
- this.get("num_flagged_by_users") <= this.get("max_flagged_by_users"),
- likes_given: this.get("num_likes_given") >= this.get("min_likes_given"),
- likes_received:
- this.get("num_likes_received") >= this.get("min_likes_received"),
- likes_received_days:
- this.get("num_likes_received_days") >=
- this.get("min_likes_received_days"),
- likes_received_users:
- this.get("num_likes_received_users") >=
- this.get("min_likes_received_users"),
- level_locked: this.get("trust_level_locked"),
- silenced: this.get("penalty_counts.silenced") === 0,
- suspended: this.get("penalty_counts.suspended") === 0
- };
- }.property(
+ @computed(
"days_visited",
"min_days_visited",
"num_topics_replied_to",
@@ -71,4 +42,34 @@ export default Discourse.Model.extend({
"penalty_counts.silenced",
"penalty_counts.suspended"
)
+ met() {
+ return {
+ days_visited: this.get("days_visited") >= this.get("min_days_visited"),
+ topics_replied_to:
+ this.get("num_topics_replied_to") >= this.get("min_topics_replied_to"),
+ topics_viewed: this.get("topics_viewed") >= this.get("min_topics_viewed"),
+ posts_read: this.get("posts_read") >= this.get("min_posts_read"),
+ topics_viewed_all_time:
+ this.get("topics_viewed_all_time") >=
+ this.get("min_topics_viewed_all_time"),
+ posts_read_all_time:
+ this.get("posts_read_all_time") >= this.get("min_posts_read_all_time"),
+ flagged_posts:
+ this.get("num_flagged_posts") <= this.get("max_flagged_posts"),
+ flagged_by_users:
+ this.get("num_flagged_by_users") <= this.get("max_flagged_by_users"),
+ likes_given: this.get("num_likes_given") >= this.get("min_likes_given"),
+ likes_received:
+ this.get("num_likes_received") >= this.get("min_likes_received"),
+ likes_received_days:
+ this.get("num_likes_received_days") >=
+ this.get("min_likes_received_days"),
+ likes_received_users:
+ this.get("num_likes_received_users") >=
+ this.get("min_likes_received_users"),
+ level_locked: this.get("trust_level_locked"),
+ silenced: this.get("penalty_counts.silenced") === 0,
+ suspended: this.get("penalty_counts.suspended") === 0
+ };
+ }
});
diff --git a/app/assets/javascripts/discourse/components/badge-button.js.es6 b/app/assets/javascripts/discourse/components/badge-button.js.es6
index 443bf28e09e..d0c2708b662 100644
--- a/app/assets/javascripts/discourse/components/badge-button.js.es6
+++ b/app/assets/javascripts/discourse/components/badge-button.js.es6
@@ -1,3 +1,5 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Component.extend({
tagName: "span",
classNameBindings: [
@@ -5,9 +7,12 @@ export default Ember.Component.extend({
"badge.badgeTypeClassName",
"badge.enabled::disabled"
],
- title: function() {
- return $("
" + this.get("badge.description") + "
").text();
- }.property("badge.description"),
+
+ @computed("badge.description")
+ title(badgeDescription) {
+ return $("" + badgeDescription + "
").text();
+ },
+
attributeBindings: ["data-badge-name", "title"],
"data-badge-name": Ember.computed.alias("badge.name")
});
diff --git a/app/assets/javascripts/discourse/components/basic-topic-list.js.es6 b/app/assets/javascripts/discourse/components/basic-topic-list.js.es6
index e5660aa98e4..651dac43278 100644
--- a/app/assets/javascripts/discourse/components/basic-topic-list.js.es6
+++ b/app/assets/javascripts/discourse/components/basic-topic-list.js.es6
@@ -1,15 +1,18 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Component.extend({
loadingMore: Ember.computed.alias("topicList.loadingMore"),
loading: Ember.computed.not("loaded"),
- loaded: function() {
+ @computed("topicList.loaded")
+ loaded() {
var topicList = this.get("topicList");
if (topicList) {
return topicList.get("loaded");
} else {
return true;
}
- }.property("topicList.loaded"),
+ },
_topicListChanged: function() {
this._initFromTopicList(this.get("topicList"));
@@ -27,9 +30,6 @@ export default Ember.Component.extend({
const topicList = this.get("topicList");
if (topicList) {
this._initFromTopicList(topicList);
- } else {
- // Without a topic list, we assume it's loaded always.
- this.set("loaded", true);
}
},
diff --git a/app/assets/javascripts/discourse/components/d-button.js.es6 b/app/assets/javascripts/discourse/components/d-button.js.es6
index 7fbf32bc184..30ae320f089 100644
--- a/app/assets/javascripts/discourse/components/d-button.js.es6
+++ b/app/assets/javascripts/discourse/components/d-button.js.es6
@@ -30,13 +30,25 @@ export default Ember.Component.extend({
noText: Ember.computed.empty("translatedLabel"),
@computed("title")
- translatedTitle(title) {
- if (title) return I18n.t(title);
+ translatedTitle: {
+ get() {
+ if (this._translatedTitle) return this._translatedTitle;
+ if (this.title) return I18n.t(this.title);
+ },
+ set(value) {
+ return (this._translatedTitle = value);
+ }
},
@computed("label")
- translatedLabel(label) {
- if (label) return I18n.t(label);
+ translatedLabel: {
+ get() {
+ if (this._translatedLabel) return this._translatedLabel;
+ if (this.label) return I18n.t(this.label);
+ },
+ set(value) {
+ return (this._translatedLabel = value);
+ }
},
click() {
diff --git a/app/assets/javascripts/discourse/components/discourse-banner.js.es6 b/app/assets/javascripts/discourse/components/discourse-banner.js.es6
index e737d476437..80997b4c9cb 100644
--- a/app/assets/javascripts/discourse/components/discourse-banner.js.es6
+++ b/app/assets/javascripts/discourse/components/discourse-banner.js.es6
@@ -1,9 +1,10 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Component.extend({
- visible: function() {
- var bannerKey = this.get("banner.key"),
- dismissedBannerKey =
- this.get("user.dismissed_banner_key") ||
- this.keyValueStore.get("dismissed_banner_key");
+ @computed("user.dismissed_banner_key", "banner.key", "hide")
+ visible(dismissedBannerKey, bannerKey, hide) {
+ dismissedBannerKey =
+ dismissedBannerKey || this.keyValueStore.get("dismissed_banner_key");
if (bannerKey) {
bannerKey = parseInt(bannerKey, 10);
@@ -12,8 +13,8 @@ export default Ember.Component.extend({
dismissedBannerKey = parseInt(dismissedBannerKey, 10);
}
- return !this.get("hide") && bannerKey && dismissedBannerKey !== bannerKey;
- }.property("user.dismissed_banner_key", "banner.key", "hide"),
+ return !hide && bannerKey && dismissedBannerKey !== bannerKey;
+ },
actions: {
dismiss() {
diff --git a/app/assets/javascripts/discourse/components/discourse-tag-bound.js.es6 b/app/assets/javascripts/discourse/components/discourse-tag-bound.js.es6
index c422c5dd0e7..9f151dc1fe3 100644
--- a/app/assets/javascripts/discourse/components/discourse-tag-bound.js.es6
+++ b/app/assets/javascripts/discourse/components/discourse-tag-bound.js.es6
@@ -1,13 +1,17 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Component.extend({
tagName: "a",
classNameBindings: [":discourse-tag", "style", "tagClass"],
attributeBindings: ["href"],
- tagClass: function() {
- return "tag-" + this.get("tagRecord.id");
- }.property("tagRecord.id"),
+ @computed("tagRecord.id")
+ tagClass(tagRecordId) {
+ return "tag-" + tagRecordId;
+ },
- href: function() {
- return Discourse.getURL("/tags/" + this.get("tagRecord.id"));
- }.property("tagRecord.id")
+ @computed("tagRecord.id")
+ href(tagRecordId) {
+ return Discourse.getURL("/tags/" + tagRecordId);
+ }
});
diff --git a/app/assets/javascripts/discourse/components/edit-category-tab.js.es6 b/app/assets/javascripts/discourse/components/edit-category-tab.js.es6
index 7c2509f0680..50fd860f2b2 100644
--- a/app/assets/javascripts/discourse/components/edit-category-tab.js.es6
+++ b/app/assets/javascripts/discourse/components/edit-category-tab.js.es6
@@ -1,18 +1,21 @@
import { propertyEqual } from "discourse/lib/computed";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({
tagName: "li",
classNameBindings: ["active", "tabClassName"],
- tabClassName: function() {
- return "edit-category-" + this.get("tab");
- }.property("tab"),
+ @computed("tab")
+ tabClassName(tab) {
+ return "edit-category-" + tab;
+ },
active: propertyEqual("selectedTab", "tab"),
- title: function() {
- return I18n.t("category." + this.get("tab").replace("-", "_"));
- }.property("tab"),
+ @computed("tab")
+ title(tab) {
+ return I18n.t("category." + tab.replace("-", "_"));
+ },
didInsertElement() {
this._super(...arguments);
diff --git a/app/assets/javascripts/discourse/components/preference-checkbox.js.es6 b/app/assets/javascripts/discourse/components/preference-checkbox.js.es6
index 6088f4a4a6b..1b858735a24 100644
--- a/app/assets/javascripts/discourse/components/preference-checkbox.js.es6
+++ b/app/assets/javascripts/discourse/components/preference-checkbox.js.es6
@@ -1,9 +1,12 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Component.extend({
classNames: ["controls"],
- label: function() {
- return I18n.t(this.get("labelKey"));
- }.property("labelKey"),
+ @computed("labelKey")
+ label(labelKey) {
+ return I18n.t(labelKey);
+ },
change() {
const warning = this.get("warning");
diff --git a/app/assets/javascripts/discourse/components/tag-drop-link.js.es6 b/app/assets/javascripts/discourse/components/tag-drop-link.js.es6
index 55de68c4145..099f2b8449a 100644
--- a/app/assets/javascripts/discourse/components/tag-drop-link.js.es6
+++ b/app/assets/javascripts/discourse/components/tag-drop-link.js.es6
@@ -1,4 +1,5 @@
import DiscourseURL from "discourse/lib/url";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({
tagName: "a",
@@ -10,17 +11,19 @@ export default Ember.Component.extend({
],
attributeBindings: ["href"],
- href: function() {
+ @computed("tagId", "category")
+ href(tagId, category) {
var url = "/tags";
- if (this.get("category")) {
- url += this.get("category.url");
+ if (category) {
+ url += category.url;
}
- return url + "/" + this.get("tagId");
- }.property("tagId", "category"),
+ return url + "/" + tagId;
+ },
- tagClass: function() {
- return "tag-" + this.get("tagId");
- }.property("tagId"),
+ @computed("tagId")
+ tagClass(tagId) {
+ return "tag-" + tagId;
+ },
click(e) {
e.preventDefault();
diff --git a/app/assets/javascripts/discourse/components/text-field.js.es6 b/app/assets/javascripts/discourse/components/text-field.js.es6
index 908e52389e4..eca66af1d36 100644
--- a/app/assets/javascripts/discourse/components/text-field.js.es6
+++ b/app/assets/javascripts/discourse/components/text-field.js.es6
@@ -38,7 +38,13 @@ export default Ember.TextField.extend({
},
@computed("placeholderKey")
- placeholder(placeholderKey) {
- return placeholderKey ? I18n.t(placeholderKey) : "";
+ placeholder: {
+ get() {
+ if (this._placeholder) return this._placeholder;
+ return this.placeholderKey ? I18n.t(this.placeholderKey) : "";
+ },
+ set(value) {
+ return (this._placeholder = value);
+ }
}
});
diff --git a/app/assets/javascripts/discourse/components/top-period-buttons.js.es6 b/app/assets/javascripts/discourse/components/top-period-buttons.js.es6
index 237a4c6cfe0..059b1a1468c 100644
--- a/app/assets/javascripts/discourse/components/top-period-buttons.js.es6
+++ b/app/assets/javascripts/discourse/components/top-period-buttons.js.es6
@@ -1,10 +1,12 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Component.extend({
classNames: ["top-title-buttons"],
- periods: function() {
- const period = this.get("period");
+ @computed("period")
+ periods(period) {
return this.site.get("periods").filter(p => p !== period);
- }.property("period"),
+ },
actions: {
changePeriod(p) {
diff --git a/app/assets/javascripts/discourse/components/topic-list.js.es6 b/app/assets/javascripts/discourse/components/topic-list.js.es6
index a91ee52c0b8..f08140142f0 100644
--- a/app/assets/javascripts/discourse/components/topic-list.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-list.js.es6
@@ -1,4 +1,7 @@
-import { observes } from "ember-addons/ember-computed-decorators";
+import {
+ default as computed,
+ observes
+} from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({
tagName: "table",
@@ -16,25 +19,25 @@ export default Ember.Component.extend({
this.refreshLastVisited();
}.on("init"),
- toggleInTitle: function() {
- return !this.get("bulkSelectEnabled") && this.get("canBulkSelect");
- }.property("bulkSelectEnabled"),
+ @computed("bulkSelectEnabled")
+ toggleInTitle(bulkSelectEnabled) {
+ return !bulkSelectEnabled && this.get("canBulkSelect");
+ },
- sortable: function() {
+ @computed
+ sortable() {
return !!this.get("changeSort");
- }.property(),
+ },
- skipHeader: function() {
- return this.site.mobileView;
- }.property(),
+ @computed("order")
+ showLikes(order) {
+ return order === "likes";
+ },
- showLikes: function() {
- return this.get("order") === "likes";
- }.property("order"),
-
- showOpLikes: function() {
- return this.get("order") === "op_likes";
- }.property("order"),
+ @computed("order")
+ showOpLikes(order) {
+ return order === "op_likes";
+ },
@observes("topics.[]")
topicsAdded() {
diff --git a/app/assets/javascripts/discourse/components/topic-status.js.es6 b/app/assets/javascripts/discourse/components/topic-status.js.es6
index 9e92561ea6f..866ed66f879 100644
--- a/app/assets/javascripts/discourse/components/topic-status.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-status.js.es6
@@ -2,6 +2,7 @@ import { iconHTML } from "discourse-common/lib/icon-library";
import { bufferedRender } from "discourse-common/lib/buffered-render";
import { escapeExpression } from "discourse/lib/utilities";
import TopicStatusIcons from "discourse/helpers/topic-status-icons";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend(
bufferedRender({
@@ -26,9 +27,10 @@ export default Ember.Component.extend(
return false;
},
- canAct: function() {
- return Discourse.User.current() && !this.get("disableActions");
- }.property("disableActions"),
+ @computed("disableActions")
+ canAct(disableActions) {
+ return Discourse.User.current() && !disableActions;
+ },
buildBuffer(buffer) {
const canAct = this.get("canAct");
diff --git a/app/assets/javascripts/discourse/components/user-badge.js.es6 b/app/assets/javascripts/discourse/components/user-badge.js.es6
index 70636d347fd..bca90d4435a 100644
--- a/app/assets/javascripts/discourse/components/user-badge.js.es6
+++ b/app/assets/javascripts/discourse/components/user-badge.js.es6
@@ -1,14 +1,18 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Component.extend({
tagName: "span",
- showGrantCount: function() {
- return this.get("count") && this.get("count") > 1;
- }.property("count"),
+ @computed("count")
+ showGrantCount(count) {
+ return count && count > 1;
+ },
- badgeUrl: function() {
+ @computed("badge", "user")
+ badgeUrl() {
// NOTE: I tried using a link-to helper here but the queryParams mean it fails
var username = this.get("user.username_lower") || "";
username = username !== "" ? "?username=" + username : "";
return this.get("badge.url") + username;
- }.property("badge", "user")
+ }
});
diff --git a/app/assets/javascripts/discourse/components/user-field.js.es6 b/app/assets/javascripts/discourse/components/user-field.js.es6
index 79a19c20467..1585e9a3a5a 100644
--- a/app/assets/javascripts/discourse/components/user-field.js.es6
+++ b/app/assets/javascripts/discourse/components/user-field.js.es6
@@ -1,10 +1,12 @@
import { fmt } from "discourse/lib/computed";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Component.extend({
classNameBindings: [":user-field", "field.field_type"],
layoutName: fmt("field.field_type", "components/user-fields/%@"),
- noneLabel: function() {
+ @computed
+ noneLabel() {
return "user_fields.none";
- }.property()
+ }
});
diff --git a/app/assets/javascripts/discourse/controllers/about.js.es6 b/app/assets/javascripts/discourse/controllers/about.js.es6
index a3c77bbaea8..f17aac609be 100644
--- a/app/assets/javascripts/discourse/controllers/about.js.es6
+++ b/app/assets/javascripts/discourse/controllers/about.js.es6
@@ -1,7 +1,10 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Controller.extend({
faqOverriden: Ember.computed.gt("siteSettings.faq_url.length", 0),
- contactInfo: function() {
+ @computed
+ contactInfo() {
if (this.siteSettings.contact_url) {
return I18n.t("about.contact_info", {
contact_info:
@@ -18,5 +21,5 @@ export default Ember.Controller.extend({
} else {
return null;
}
- }.property()
+ }
});
diff --git a/app/assets/javascripts/discourse/controllers/badges/index.js.es6 b/app/assets/javascripts/discourse/controllers/badges/index.js.es6
index 6da107ec568..eb36dbe5219 100644
--- a/app/assets/javascripts/discourse/controllers/badges/index.js.es6
+++ b/app/assets/javascripts/discourse/controllers/badges/index.js.es6
@@ -1,6 +1,9 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Controller.extend({
- badgeGroups: function() {
- var sorted = _.sortBy(this.get("model"), function(badge) {
+ @computed("model")
+ badgeGroups(model) {
+ var sorted = _.sortBy(model, function(badge) {
var pos = badge.get("badge_grouping.position");
var type = badge.get("badge_type_id");
var name = badge.get("name");
@@ -31,5 +34,5 @@ export default Ember.Controller.extend({
}
return grouped;
- }.property("model")
+ }
});
diff --git a/app/assets/javascripts/discourse/controllers/badges/show.js.es6 b/app/assets/javascripts/discourse/controllers/badges/show.js.es6
index a5273c253b1..1fcda3adf7c 100644
--- a/app/assets/javascripts/discourse/controllers/badges/show.js.es6
+++ b/app/assets/javascripts/discourse/controllers/badges/show.js.es6
@@ -12,9 +12,10 @@ export default Ember.Controller.extend(BadgeSelectController, {
application: Ember.inject.controller(),
hiddenSetTitle: true,
- filteredList: function() {
- return this.get("userBadgesAll").filterBy("badge.allow_title", true);
- }.property("userBadgesAll"),
+ @computed("userBadgesAll")
+ filteredList(userBadgesAll) {
+ return userBadgesAll.filterBy("badge.allow_title", true);
+ },
@computed("username")
user(username) {
diff --git a/app/assets/javascripts/discourse/controllers/composer.js.es6 b/app/assets/javascripts/discourse/controllers/composer.js.es6
index be239a81e73..9a370cee026 100644
--- a/app/assets/javascripts/discourse/controllers/composer.js.es6
+++ b/app/assets/javascripts/discourse/controllers/composer.js.es6
@@ -39,6 +39,7 @@ function loadDraft(store, opts) {
((draft.title && draft.title !== "") || (draft.reply && draft.reply !== ""))
) {
const composer = store.createRecord("composer");
+
composer.open({
draftKey,
draftSequence,
@@ -301,14 +302,12 @@ export default Ember.Controller.extend({
}
},
- showWarning: function() {
+ @computed("model.creatingPrivateMessage", "model.targetUsernames")
+ showWarning(creatingPrivateMessage, usernames) {
if (!Discourse.User.currentProp("staff")) {
return false;
}
-
- var usernames = this.get("model.targetUsernames");
var hasTargetGroups = this.get("model.hasTargetGroups");
-
// We need exactly one user to issue a warning
if (
Ember.isEmpty(usernames) ||
@@ -317,8 +316,8 @@ export default Ember.Controller.extend({
) {
return false;
}
- return this.get("model.creatingPrivateMessage");
- }.property("model.creatingPrivateMessage", "model.targetUsernames"),
+ return creatingPrivateMessage;
+ },
@computed("model.topic")
draftTitle(topic) {
@@ -1102,15 +1101,13 @@ export default Ember.Controller.extend({
$(".d-editor-input").autocomplete({ cancel: true });
},
- canEdit: function() {
- return (
- this.get("model.action") === "edit" &&
- Discourse.User.current().get("can_edit")
- );
- }.property("model.action"),
+ @computed("model.action")
+ canEdit(action) {
+ return action === "edit" && Discourse.User.current().get("can_edit");
+ },
- visible: function() {
- var state = this.get("model.composeState");
+ @computed("model.composeState")
+ visible(state) {
return state && state !== "closed";
- }.property("model.composeState")
+ }
});
diff --git a/app/assets/javascripts/discourse/controllers/create-account.js.es6 b/app/assets/javascripts/discourse/controllers/create-account.js.es6
index cb38b10d30c..7b88f79927e 100644
--- a/app/assets/javascripts/discourse/controllers/create-account.js.es6
+++ b/app/assets/javascripts/discourse/controllers/create-account.js.es6
@@ -1,7 +1,10 @@
import { ajax } from "discourse/lib/ajax";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { setting } from "discourse/lib/computed";
-import { on } from "ember-addons/ember-computed-decorators";
+import {
+ default as computed,
+ on
+} from "ember-addons/ember-computed-decorators";
import { emailValid } from "discourse/lib/utilities";
import InputValidation from "discourse/models/input-validation";
import PasswordValidation from "discourse/mixins/password-validation";
@@ -51,7 +54,16 @@ export default Ember.Controller.extend(
this._createUserFields();
},
- submitDisabled: function() {
+ @computed(
+ "passwordRequired",
+ "nameValidation.failed",
+ "emailValidation.failed",
+ "usernameValidation.failed",
+ "passwordValidation.failed",
+ "userFieldsValidation.failed",
+ "formSubmitted"
+ )
+ submitDisabled() {
if (!this.get("emailValidation.failed") && !this.get("passwordRequired"))
return false; // 3rd party auth
if (this.get("formSubmitted")) return true;
@@ -62,51 +74,44 @@ export default Ember.Controller.extend(
if (this.get("userFieldsValidation.failed")) return true;
return false;
- }.property(
- "passwordRequired",
- "nameValidation.failed",
- "emailValidation.failed",
- "usernameValidation.failed",
- "passwordValidation.failed",
- "userFieldsValidation.failed",
- "formSubmitted"
- ),
+ },
usernameRequired: Ember.computed.not("authOptions.omit_username"),
- fullnameRequired: function() {
+ @computed
+ fullnameRequired() {
return (
this.get("siteSettings.full_name_required") ||
this.get("siteSettings.enable_names")
);
- }.property(),
+ },
- passwordRequired: function() {
- return Ember.isEmpty(this.get("authOptions.auth_provider"));
- }.property("authOptions.auth_provider"),
+ @computed("authOptions.auth_provider")
+ passwordRequired(authProvider) {
+ return Ember.isEmpty(authProvider);
+ },
- disclaimerHtml: function() {
+ @computed
+ disclaimerHtml() {
return I18n.t("create_account.disclaimer", {
tos_link: this.get("siteSettings.tos_url") || Discourse.getURL("/tos"),
privacy_link:
this.get("siteSettings.privacy_policy_url") ||
Discourse.getURL("/privacy")
});
- }.property(),
+ },
// Check the email address
- emailValidation: function() {
+ @computed("accountEmail", "rejectedEmails.[]")
+ emailValidation(email, rejectedEmails) {
// If blank, fail without a reason
- let email;
- if (Ember.isEmpty(this.get("accountEmail"))) {
+ if (Ember.isEmpty(email)) {
return InputValidation.create({
failed: true
});
}
- email = this.get("accountEmail");
-
- if (this.get("rejectedEmails").includes(email)) {
+ if (rejectedEmails.includes(email)) {
return InputValidation.create({
failed: true,
reason: I18n.t("user.email.invalid")
@@ -138,14 +143,15 @@ export default Ember.Controller.extend(
failed: true,
reason: I18n.t("user.email.invalid")
});
- }.property("accountEmail", "rejectedEmails.[]"),
+ },
- emailValidated: function() {
+ @computed("accountEmail", "authOptions.email", "authOptions.email_valid")
+ emailValidated() {
return (
this.get("authOptions.email") === this.get("accountEmail") &&
this.get("authOptions.email_valid")
);
- }.property("accountEmail", "authOptions.email", "authOptions.email_valid"),
+ },
authProviderDisplayName(providerName) {
const matchingProvider = findAll().find(provider => {
@@ -178,9 +184,10 @@ export default Ember.Controller.extend(
}.observes("emailValidation", "accountEmail"),
// Determines whether at least one login button is enabled
- hasAtLeastOneLoginButton: function() {
+ @computed
+ hasAtLeastOneLoginButton() {
return findAll(this.siteSettings).length > 0;
- }.property(),
+ },
@on("init")
fetchConfirmationValue() {
diff --git a/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6 b/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
index 709deffbaa1..3f64d5984eb 100644
--- a/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
+++ b/app/assets/javascripts/discourse/controllers/discovery/topics.js.es6
@@ -5,6 +5,7 @@ import { endWith } from "discourse/lib/computed";
import showModal from "discourse/lib/show-modal";
import { userPath } from "discourse/lib/url";
import TopicList from "discourse/models/topic-list";
+import computed from "ember-addons/ember-computed-decorators";
const controllerOpts = {
discovery: Ember.inject.controller(),
@@ -96,26 +97,24 @@ const controllerOpts = {
return filter.match(new RegExp(filterType + "$", "gi")) ? true : false;
},
- showDismissRead: function() {
- return (
- this.isFilterPage(this.get("model.filter"), "unread") &&
- this.get("model.topics.length") > 0
- );
- }.property("model.filter", "model.topics.length"),
+ @computed("model.filter", "model.topics.length")
+ showDismissRead(filter, topicsLength) {
+ return this.isFilterPage(filter, "unread") && topicsLength > 0;
+ },
- showResetNew: function() {
- return (
- this.get("model.filter") === "new" && this.get("model.topics.length") > 0
- );
- }.property("model.filter", "model.topics.length"),
+ @computed("model.filter", "model.topics.length")
+ showResetNew(filter, topicsLength) {
+ return filter === "new" && topicsLength > 0;
+ },
- showDismissAtTop: function() {
+ @computed("model.filter", "model.topics.length")
+ showDismissAtTop(filter, topicsLength) {
return (
- (this.isFilterPage(this.get("model.filter"), "new") ||
- this.isFilterPage(this.get("model.filter"), "unread")) &&
- this.get("model.topics.length") >= 15
+ (this.isFilterPage(filter, "new") ||
+ this.isFilterPage(filter, "unread")) &&
+ topicsLength >= 15
);
- }.property("model.filter", "model.topics.length"),
+ },
hasTopics: Ember.computed.gt("model.topics.length", 0),
allLoaded: Ember.computed.empty("model.more_topics_url"),
@@ -128,10 +127,9 @@ const controllerOpts = {
weekly: Ember.computed.equal("period", "weekly"),
daily: Ember.computed.equal("period", "daily"),
- footerMessage: function() {
- if (!this.get("allLoaded")) {
- return;
- }
+ @computed("allLoaded", "model.topics.length")
+ footerMessage(allLoaded, topicsLength) {
+ if (!allLoaded) return;
const category = this.get("category");
if (category) {
@@ -140,7 +138,7 @@ const controllerOpts = {
});
} else {
const split = (this.get("model.filter") || "").split("/");
- if (this.get("model.topics.length") === 0) {
+ if (topicsLength === 0) {
return I18n.t("topics.none." + split[0], {
category: split[1]
});
@@ -150,14 +148,11 @@ const controllerOpts = {
});
}
}
- }.property("allLoaded", "model.topics.length"),
+ },
- footerEducation: function() {
- if (
- !this.get("allLoaded") ||
- this.get("model.topics.length") > 0 ||
- !this.currentUser
- ) {
+ @computed("allLoaded", "model.topics.length")
+ footerEducation(allLoaded, topicsLength) {
+ if (!allLoaded || topicsLength > 0 || !this.currentUser) {
return;
}
@@ -173,7 +168,7 @@ const controllerOpts = {
`${this.currentUser.get("username_lower")}/preferences`
)
});
- }.property("allLoaded", "model.topics.length")
+ }
};
Object.keys(queryParams).forEach(function(p) {
diff --git a/app/assets/javascripts/discourse/controllers/edit-category.js.es6 b/app/assets/javascripts/discourse/controllers/edit-category.js.es6
index d474c9b6e51..fc616f19d96 100644
--- a/app/assets/javascripts/discourse/controllers/edit-category.js.es6
+++ b/app/assets/javascripts/discourse/controllers/edit-category.js.es6
@@ -1,6 +1,7 @@
import ModalFunctionality from "discourse/mixins/modal-functionality";
import DiscourseURL from "discourse/lib/url";
import { extractError } from "discourse/lib/ajax-error";
+import computed from "ember-addons/ember-computed-decorators";
// Modal for editing / creating a category
export default Ember.Controller.extend(ModalFunctionality, {
@@ -28,39 +29,44 @@ export default Ember.Controller.extend(ModalFunctionality, {
}
}.observes("model.description"),
- title: function() {
- if (this.get("model.id")) {
+ @computed("model.id", "model.name")
+ title(id, name) {
+ if (id) {
return I18n.t("category.edit_dialog_title", {
- categoryName: this.get("model.name")
+ categoryName: name
});
}
return I18n.t("category.create");
- }.property("model.id", "model.name"),
+ },
titleChanged: function() {
this.set("modal.title", this.get("title"));
}.observes("title"),
- disabled: function() {
- if (this.get("saving") || this.get("deleting")) return true;
- if (!this.get("model.name")) return true;
- if (!this.get("model.color")) return true;
+ @computed("saving", "model.name", "model.color", "deleting")
+ disabled(saving, name, color, deleting) {
+ if (saving || deleting) return true;
+ if (!name) return true;
+ if (!color) return true;
return false;
- }.property("saving", "model.name", "model.color", "deleting"),
+ },
- deleteDisabled: function() {
- return this.get("deleting") || this.get("saving") || false;
- }.property("disabled", "saving", "deleting"),
+ @computed("saving", "deleting")
+ deleteDisabled(saving, deleting) {
+ return deleting || saving || false;
+ },
- categoryName: function() {
- const name = this.get("name") || "";
+ @computed("name")
+ categoryName(name) {
+ name = name || "";
return name.trim().length > 0 ? name : I18n.t("preview");
- }.property("name"),
+ },
- saveLabel: function() {
- if (this.get("saving")) return "saving";
- return this.get("model.id") ? "category.save" : "category.create";
- }.property("saving", "model.id"),
+ @computed("saving", "model.id")
+ saveLabel(saving, id) {
+ if (saving) return "saving";
+ return id ? "category.save" : "category.create";
+ },
actions: {
saveCategory() {
diff --git a/app/assets/javascripts/discourse/controllers/exception.js.es6 b/app/assets/javascripts/discourse/controllers/exception.js.es6
index 331dc5e6947..0009df44ed7 100644
--- a/app/assets/javascripts/discourse/controllers/exception.js.es6
+++ b/app/assets/javascripts/discourse/controllers/exception.js.es6
@@ -1,3 +1,5 @@
+import computed from "ember-addons/ember-computed-decorators";
+
var ButtonBackBright = {
classes: "btn-primary",
action: "back",
@@ -25,13 +27,14 @@ export default Ember.Controller.extend({
thrown: null,
lastTransition: null,
+ @computed
isNetwork: function() {
// never made it on the wire
if (this.get("thrown.readyState") === 0) return true;
// timed out
if (this.get("thrown.jqTextStatus") === "timeout") return true;
return false;
- }.property(),
+ },
isNotFound: Ember.computed.equal("thrown.status", 404),
isForbidden: Ember.computed.equal("thrown.status", 403),
@@ -48,7 +51,8 @@ export default Ember.Controller.extend({
this.set("loading", false);
}.on("init"),
- reason: function() {
+ @computed("isNetwork", "isServer", "isUnknown")
+ reason() {
if (this.get("isNetwork")) {
return I18n.t("errors.reasons.network");
} else if (this.get("isServer")) {
@@ -61,11 +65,12 @@ export default Ember.Controller.extend({
// TODO
return I18n.t("errors.reasons.unknown");
}
- }.property("isNetwork", "isServer", "isUnknown"),
+ },
requestUrl: Ember.computed.alias("thrown.requestedUrl"),
- desc: function() {
+ @computed("networkFixed", "isNetwork", "isServer", "isUnknown")
+ desc() {
if (this.get("networkFixed")) {
return I18n.t("errors.desc.network_fixed");
} else if (this.get("isNetwork")) {
@@ -80,9 +85,10 @@ export default Ember.Controller.extend({
// TODO
return I18n.t("errors.desc.unknown");
}
- }.property("networkFixed", "isNetwork", "isServer", "isUnknown"),
+ },
- enabledButtons: function() {
+ @computed("networkFixed", "isNetwork", "isServer", "isUnknown")
+ enabledButtons() {
if (this.get("networkFixed")) {
return [ButtonLoadPage];
} else if (this.get("isNetwork")) {
@@ -90,7 +96,7 @@ export default Ember.Controller.extend({
} else {
return [ButtonBackBright, ButtonTryAgain];
}
- }.property("networkFixed", "isNetwork", "isServer", "isUnknown"),
+ },
actions: {
back: function() {
diff --git a/app/assets/javascripts/discourse/controllers/flag.js.es6 b/app/assets/javascripts/discourse/controllers/flag.js.es6
index a6fbef909e6..2c0fd7704c5 100644
--- a/app/assets/javascripts/discourse/controllers/flag.js.es6
+++ b/app/assets/javascripts/discourse/controllers/flag.js.es6
@@ -39,7 +39,8 @@ export default Ember.Controller.extend(ModalFunctionality, {
return flagTopic ? "flagging_topic.title" : "flagging.title";
},
- flagsAvailable: function() {
+ @computed("post", "flagTopic", "model.actions_summary.@each.can_act")
+ flagsAvailable() {
if (!this.get("flagTopic")) {
// flagging post
let flagsAvailable = this.get("model.flagsAvailable");
@@ -71,16 +72,18 @@ export default Ember.Controller.extend(ModalFunctionality, {
});
});
}
- }.property("post", "flagTopic", "model.actions_summary.@each.can_act"),
+ },
- staffFlagsAvailable: function() {
+ @computed("post", "flagTopic", "model.actions_summary.@each.can_act")
+ staffFlagsAvailable() {
return (
this.get("model.flagsAvailable") &&
this.get("model.flagsAvailable").length > 1
);
- }.property("post", "flagTopic", "model.actions_summary.@each.can_act"),
+ },
- submitEnabled: function() {
+ @computed("selected.is_custom_flag", "message.length")
+ submitEnabled() {
const selected = this.get("selected");
if (!selected) return false;
@@ -92,7 +95,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
);
}
return true;
- }.property("selected.is_custom_flag", "message.length"),
+ },
submitDisabled: Ember.computed.not("submitEnabled"),
diff --git a/app/assets/javascripts/discourse/controllers/login.js.es6 b/app/assets/javascripts/discourse/controllers/login.js.es6
index 1be438faea9..bba1b31bcf8 100644
--- a/app/assets/javascripts/discourse/controllers/login.js.es6
+++ b/app/assets/javascripts/discourse/controllers/login.js.es6
@@ -284,17 +284,18 @@ export default Ember.Controller.extend(ModalFunctionality, {
}
},
- authMessage: function() {
- if (Ember.isEmpty(this.get("authenticate"))) return "";
+ @computed("authenticate")
+ authMessage(authenticate) {
+ if (Ember.isEmpty(authenticate)) return "";
const method = findAll(
this.siteSettings,
this.capabilities,
this.isMobileDevice
- ).findBy("name", this.get("authenticate"));
+ ).findBy("name", authenticate);
if (method) {
return method.get("message");
}
- }.property("authenticate"),
+ },
authenticationComplete(options) {
const self = this;
diff --git a/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6 b/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6
index acaa6d5458c..ee6066f1863 100644
--- a/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6
+++ b/app/assets/javascripts/discourse/controllers/navigation/categories.js.es6
@@ -1,9 +1,11 @@
import NavigationDefaultController from "discourse/controllers/navigation/default";
+import computed from "ember-addons/ember-computed-decorators";
export default NavigationDefaultController.extend({
discoveryCategories: Ember.inject.controller("discovery/categories"),
- draft: function() {
+ @computed("discoveryCategories.model", "discoveryCategories.model.draft")
+ draft() {
return this.get("discoveryCategories.model.draft");
- }.property("discoveryCategories.model", "discoveryCategories.model.draft")
+ }
});
diff --git a/app/assets/javascripts/discourse/controllers/navigation/default.js.es6 b/app/assets/javascripts/discourse/controllers/navigation/default.js.es6
index f8d0b330853..0ad18786224 100644
--- a/app/assets/javascripts/discourse/controllers/navigation/default.js.es6
+++ b/app/assets/javascripts/discourse/controllers/navigation/default.js.es6
@@ -1,8 +1,11 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Controller.extend({
discovery: Ember.inject.controller(),
discoveryTopics: Ember.inject.controller("discovery/topics"),
+ @computed("discoveryTopics.model", "discoveryTopics.model.draft")
draft: function() {
return this.get("discoveryTopics.model.draft");
- }.property("discoveryTopics.model", "discoveryTopics.model.draft")
+ }
});
diff --git a/app/assets/javascripts/discourse/controllers/preferences/about.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/about.js.es6
index cd1392f1a39..37e7247a8ab 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/about.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/about.js.es6
@@ -1,8 +1,11 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Controller.extend({
saving: false,
newBio: null,
- saveButtonText: function() {
- return this.get("saving") ? I18n.t("saving") : I18n.t("user.change");
- }.property("saving")
+ @computed("saving")
+ saveButtonText(saving) {
+ return saving ? I18n.t("saving") : I18n.t("user.change");
+ }
});
diff --git a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
index 8629f612556..ed36721e386 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
@@ -77,9 +77,10 @@ export default Ember.Controller.extend(PreferencesTabController, {
});
},
- userSelectableThemes: function() {
+ @computed
+ userSelectableThemes() {
return listThemes(this.site);
- }.property(),
+ },
@computed("userSelectableThemes")
showThemeSelector(themes) {
diff --git a/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6 b/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
index f3cac072d79..a3ccdf3bce2 100644
--- a/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
+++ b/app/assets/javascripts/discourse/controllers/reorder-categories.js.es6
@@ -26,13 +26,14 @@ export default Ember.Controller.extend(ModalFunctionality, Ember.Evented, {
"categoriesSorting"
),
- showApplyAll: function() {
+ @computed("categoriesBuffered.@each.hasBufferedChanges")
+ showApplyAll() {
let anyChanged = false;
this.get("categoriesBuffered").forEach(bc => {
anyChanged = anyChanged || bc.get("hasBufferedChanges");
});
return anyChanged;
- }.property("categoriesBuffered.@each.hasBufferedChanges"),
+ },
moveDir(cat, dir) {
const cats = this.get("categoriesOrdered");
diff --git a/app/assets/javascripts/discourse/controllers/search-help.js.es6 b/app/assets/javascripts/discourse/controllers/search-help.js.es6
index efbb4663243..be04358f4bf 100644
--- a/app/assets/javascripts/discourse/controllers/search-help.js.es6
+++ b/app/assets/javascripts/discourse/controllers/search-help.js.es6
@@ -1,7 +1,9 @@
import ModalFunctionality from "discourse/mixins/modal-functionality";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend(ModalFunctionality, {
- showGoogleSearch: function() {
+ @computed
+ showGoogleSearch() {
return !Discourse.SiteSettings.login_required;
- }.property()
+ }
});
diff --git a/app/assets/javascripts/discourse/controllers/user-private-messages.js.es6 b/app/assets/javascripts/discourse/controllers/user-private-messages.js.es6
index 6091a569c06..917f552709b 100644
--- a/app/assets/javascripts/discourse/controllers/user-private-messages.js.es6
+++ b/app/assets/javascripts/discourse/controllers/user-private-messages.js.es6
@@ -16,12 +16,12 @@ export default Ember.Controller.extend({
pmTaggingEnabled: Ember.computed.alias("site.can_tag_pms"),
tagId: null,
- showNewPM: function() {
+ @computed("user.viewingSelf")
+ showNewPM(viewingSelf) {
return (
- this.get("user.viewingSelf") &&
- Discourse.User.currentProp("can_send_private_messages")
+ viewingSelf && Discourse.User.currentProp("can_send_private_messages")
);
- }.property("user.viewingSelf"),
+ },
@computed("selected.[]", "bulkSelectEnabled")
hasSelection(selected, bulkSelectEnabled) {
diff --git a/app/assets/javascripts/discourse/lib/computed.js.es6 b/app/assets/javascripts/discourse/lib/computed.js.es6
index c70d80d5150..52788ddca9b 100644
--- a/app/assets/javascripts/discourse/lib/computed.js.es6
+++ b/app/assets/javascripts/discourse/lib/computed.js.es6
@@ -1,4 +1,5 @@
import addonFmt from "ember-addons/fmt";
+
/**
Returns whether two properties are equal to each other.
@@ -7,10 +8,11 @@ import addonFmt from "ember-addons/fmt";
@params {String} p2 the second property
@return {Function} computedProperty function
**/
+
export function propertyEqual(p1, p2) {
- return Ember.computed(function() {
+ return Ember.computed(p1, p2, function() {
return this.get(p1) === this.get(p2);
- }).property(p1, p2);
+ });
}
/**
@@ -22,21 +24,21 @@ export function propertyEqual(p1, p2) {
@return {Function} computedProperty function
**/
export function propertyNotEqual(p1, p2) {
- return Ember.computed(function() {
+ return Ember.computed(p1, p2, function() {
return this.get(p1) !== this.get(p2);
- }).property(p1, p2);
+ });
}
export function propertyGreaterThan(p1, p2) {
- return Ember.computed(function() {
+ return Ember.computed(p1, p2, function() {
return this.get(p1) > this.get(p2);
- }).property(p1, p2);
+ });
}
export function propertyLessThan(p1, p2) {
- return Ember.computed(function() {
+ return Ember.computed(p1, p2, function() {
return this.get(p1) < this.get(p2);
- }).property(p1, p2);
+ });
}
/**
diff --git a/app/assets/javascripts/discourse/mixins/badge-select-controller.js.es6 b/app/assets/javascripts/discourse/mixins/badge-select-controller.js.es6
index 671de5801b5..b4d61fcbba5 100644
--- a/app/assets/javascripts/discourse/mixins/badge-select-controller.js.es6
+++ b/app/assets/javascripts/discourse/mixins/badge-select-controller.js.es6
@@ -1,11 +1,12 @@
import Badge from "discourse/models/badge";
+import computed from "ember-addons/ember-computed-decorators";
export default Ember.Mixin.create({
saving: false,
saved: false,
- selectableUserBadges: function() {
- let items = this.get("filteredList");
+ @computed("filteredList")
+ selectableUserBadges(items) {
items = _.uniq(items, false, function(e) {
return e.get("badge.name");
});
@@ -15,18 +16,16 @@ export default Ember.Mixin.create({
})
);
return items;
- }.property("filteredList"),
+ },
- savingStatus: function() {
- if (this.get("saving")) {
- return I18n.t("saving");
- } else {
- return I18n.t("save");
- }
- }.property("saving"),
+ @computed("saving")
+ savingStatus(saving) {
+ return saving ? I18n.t("saving") : I18n.t("save");
+ },
- selectedUserBadge: function() {
- const selectedUserBadgeId = parseInt(this.get("selectedUserBadgeId"));
+ @computed("selectedUserBadgeId")
+ selectedUserBadge(selectedUserBadgeId) {
+ selectedUserBadgeId = parseInt(selectedUserBadgeId);
let selectedUserBadge = null;
this.get("selectableUserBadges").forEach(function(userBadge) {
if (userBadge.get("id") === selectedUserBadgeId) {
@@ -34,7 +33,7 @@ export default Ember.Mixin.create({
}
});
return selectedUserBadge;
- }.property("selectedUserBadgeId"),
+ },
disableSave: Ember.computed.alias("saving")
});
diff --git a/app/assets/javascripts/discourse/models/action-summary.js.es6 b/app/assets/javascripts/discourse/models/action-summary.js.es6
index 6a2f26e2ee1..683f340be4f 100644
--- a/app/assets/javascripts/discourse/models/action-summary.js.es6
+++ b/app/assets/javascripts/discourse/models/action-summary.js.es6
@@ -3,9 +3,7 @@ import RestModel from "discourse/models/rest";
import { popupAjaxError } from "discourse/lib/ajax-error";
export default RestModel.extend({
- canToggle: function() {
- return this.get("can_undo") || this.get("can_act");
- }.property("can_undo", "can_act"),
+ canToggle: Ember.computed.or("can_undo", "can_act"),
// Remove it
removeAction: function() {
diff --git a/app/assets/javascripts/discourse/models/badge.js.es6 b/app/assets/javascripts/discourse/models/badge.js.es6
index 0658bd631f6..fc66d409668 100644
--- a/app/assets/javascripts/discourse/models/badge.js.es6
+++ b/app/assets/javascripts/discourse/models/badge.js.es6
@@ -1,13 +1,15 @@
import { ajax } from "discourse/lib/ajax";
import BadgeGrouping from "discourse/models/badge-grouping";
import RestModel from "discourse/models/rest";
+import computed from "ember-addons/ember-computed-decorators";
const Badge = RestModel.extend({
newBadge: Ember.computed.none("id"),
- url: function() {
+ @computed
+ url() {
return Discourse.getURL(`/badges/${this.get("id")}/${this.get("slug")}`);
- }.property(),
+ },
/**
Update this badge with the response returned by the server on save.
@@ -31,10 +33,11 @@ const Badge = RestModel.extend({
}
},
- badgeTypeClassName: function() {
- const type = this.get("badge_type.name") || "";
+ @computed("badge_type.name")
+ badgeTypeClassName(type) {
+ type = type || "";
return "badge-type-" + type.toLowerCase();
- }.property("badge_type.name"),
+ },
/**
Save and update the badge from the server's response.
diff --git a/app/assets/javascripts/discourse/models/composer.js.es6 b/app/assets/javascripts/discourse/models/composer.js.es6
index be08943e030..f68352e513b 100644
--- a/app/assets/javascripts/discourse/models/composer.js.es6
+++ b/app/assets/javascripts/discourse/models/composer.js.es6
@@ -77,9 +77,10 @@ const Composer = RestModel.extend({
draftSaving: false,
draftSaved: false,
- archetypes: function() {
+ @computed
+ archetypes() {
return this.site.get("archetypes");
- }.property(),
+ },
@computed("action")
sharedDraft: action => action === CREATE_SHARED_DRAFT,
@@ -184,9 +185,10 @@ const Composer = RestModel.extend({
.property()
.volatile(),
- archetype: function() {
- return this.get("archetypes").findBy("id", this.get("archetypeId"));
- }.property("archetypeId"),
+ @computed("archetypeId")
+ archetype(archetypeId) {
+ return this.get("archetypes").findBy("id", archetypeId);
+ },
archetypeChanged: function() {
return this.set("metaData", Ember.Object.create());
@@ -377,30 +379,27 @@ const Composer = RestModel.extend({
);
},
- titleLengthValid: function() {
- if (
- this.user.get("admin") &&
- this.get("post.static_doc") &&
- this.get("titleLength") > 0
- )
- return true;
- if (this.get("titleLength") < this.get("minimumTitleLength")) return false;
- return this.get("titleLength") <= this.siteSettings.max_topic_title_length;
- }.property("minimumTitleLength", "titleLength", "post.static_doc"),
+ @computed("minimumTitleLength", "titleLength", "post.static_doc")
+ titleLengthValid(minTitleLength, titleLength, staticDoc) {
+ if (this.user.get("admin") && staticDoc && titleLength > 0) return true;
+ if (titleLength < minTitleLength) return false;
+ return titleLength <= this.siteSettings.max_topic_title_length;
+ },
- hasMetaData: function() {
- const metaData = this.get("metaData");
+ @computed("metaData")
+ hasMetaData(metaData) {
return metaData ? Ember.isEmpty(Ember.keys(this.get("metaData"))) : false;
- }.property("metaData"),
+ },
/**
Did the user make changes to the reply?
@property replyDirty
**/
- replyDirty: function() {
- return this.get("reply") !== this.get("originalText");
- }.property("reply", "originalText"),
+ @computed("reply", "originalText")
+ replyDirty(reply, originalText) {
+ return reply !== originalText;
+ },
/**
Did the user make changes to the topic title?
@@ -417,9 +416,10 @@ const Composer = RestModel.extend({
@property missingTitleCharacters
**/
- missingTitleCharacters: function() {
- return this.get("minimumTitleLength") - this.get("titleLength");
- }.property("minimumTitleLength", "titleLength"),
+ @computed("minimumTitleLength", "titleLength")
+ missingTitleCharacters(minimumTitleLength, titleLength) {
+ return minimumTitleLength - titleLength;
+ },
/**
Minimum number of characters for a title to be valid.
@@ -474,23 +474,25 @@ const Composer = RestModel.extend({
@property titleLength
**/
- titleLength: function() {
- const title = this.get("title") || "";
+ @computed("title")
+ titleLength(title) {
+ title = title || "";
return title.replace(/\s+/gim, " ").trim().length;
- }.property("title"),
+ },
/**
Computes the length of the reply minus the quote(s) and non-significant whitespaces
@property replyLength
**/
- replyLength: function() {
- let reply = this.get("reply") || "";
+ @computed("reply")
+ replyLength(reply) {
+ reply = reply || "";
while (Quote.REGEXP.test(reply)) {
reply = reply.replace(Quote.REGEXP, "");
}
return reply.replace(/\s+/gim, " ").trim().length;
- }.property("reply"),
+ },
_setupComposer: function() {
this.set("archetypeId", this.site.get("default_archetype"));
diff --git a/app/assets/javascripts/discourse/models/permission-type.js.es6 b/app/assets/javascripts/discourse/models/permission-type.js.es6
index 08d15a66d8e..858be5722f3 100644
--- a/app/assets/javascripts/discourse/models/permission-type.js.es6
+++ b/app/assets/javascripts/discourse/models/permission-type.js.es6
@@ -1,8 +1,11 @@
+import computed from "ember-addons/ember-computed-decorators";
+
const PermissionType = Discourse.Model.extend({
- description: function() {
+ @computed("id")
+ description(id) {
var key = "";
- switch (this.get("id")) {
+ switch (id) {
case 1:
key = "full";
break;
@@ -14,7 +17,7 @@ const PermissionType = Discourse.Model.extend({
break;
}
return I18n.t("permission_types." + key);
- }.property("id")
+ }
});
PermissionType.FULL = 1;
diff --git a/app/assets/javascripts/discourse/models/post.js.es6 b/app/assets/javascripts/discourse/models/post.js.es6
index ac60a212461..b1a3d893168 100644
--- a/app/assets/javascripts/discourse/models/post.js.es6
+++ b/app/assets/javascripts/discourse/models/post.js.es6
@@ -17,16 +17,17 @@ const Post = RestModel.extend({
return Discourse.SiteSettings;
},
- shareUrl: function() {
+ @computed("url")
+ shareUrl(url) {
const user = Discourse.User.current();
const userSuffix = user ? "?u=" + user.get("username_lower") : "";
if (this.get("firstPost")) {
return this.get("topic.url") + userSuffix;
} else {
- return this.get("url") + userSuffix;
+ return url + userSuffix;
}
- }.property("url"),
+ },
new_user: Ember.computed.equal("trust_level", 0),
firstPost: Ember.computed.equal("post_number", 1),
@@ -36,36 +37,31 @@ const Post = RestModel.extend({
deleted: Ember.computed.or("deleted_at", "deletedViaTopic"),
notDeleted: Ember.computed.not("deleted"),
- showName: function() {
- const name = this.get("name");
+ @computed("name", "username")
+ showName(name, username) {
return (
- name &&
- name !== this.get("username") &&
- Discourse.SiteSettings.display_name_on_posts
+ name && name !== username && Discourse.SiteSettings.display_name_on_posts
);
- }.property("name", "username"),
+ },
- postDeletedBy: function() {
- if (this.get("firstPost")) {
- return this.get("topic.deleted_by");
- }
- return this.get("deleted_by");
- }.property("firstPost", "deleted_by", "topic.deleted_by"),
+ @computed("firstPost", "deleted_by", "topic.deleted_by")
+ postDeletedBy(firstPost, deletedBy, topicDeletedBy) {
+ return firstPost ? topicDeletedBy : deletedBy;
+ },
- postDeletedAt: function() {
- if (this.get("firstPost")) {
- return this.get("topic.deleted_at");
- }
- return this.get("deleted_at");
- }.property("firstPost", "deleted_at", "topic.deleted_at"),
+ @computed("firstPost", "deleted_at", "topic.deleted_at")
+ postDeletedAt(firstPost, deletedAt, topicDeletedAt) {
+ return firstPost ? topicDeletedAt : deletedAt;
+ },
- url: function() {
+ @computed("post_number", "topic_id", "topic.slug")
+ url(postNr, topicId, slug) {
return postUrl(
- this.get("topic.slug") || this.get("topic_slug"),
- this.get("topic_id") || this.get("topic.id"),
- this.get("post_number")
+ slug || this.get("topic_slug"),
+ topicId || this.get("topic.id"),
+ postNr
);
- }.property("post_number", "topic_id", "topic.slug"),
+ },
// Don't drop the /1
@computed("post_number", "url")
diff --git a/app/assets/javascripts/discourse/models/result-set.js.es6 b/app/assets/javascripts/discourse/models/result-set.js.es6
index bc36f23f76d..91101bce9d5 100644
--- a/app/assets/javascripts/discourse/models/result-set.js.es6
+++ b/app/assets/javascripts/discourse/models/result-set.js.es6
@@ -1,3 +1,5 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.ArrayProxy.extend({
loading: false,
loadingMore: false,
@@ -12,9 +14,10 @@ export default Ember.ArrayProxy.extend({
__type: null,
resultSetMeta: null,
- canLoadMore: function() {
- return this.get("length") < this.get("totalRows");
- }.property("totalRows", "length"),
+ @computed("totalRows", "length")
+ canLoadMore(totalRows, length) {
+ return length < totalRows;
+ },
loadMore() {
const loadMoreUrl = this.get("loadMoreUrl");
diff --git a/app/assets/javascripts/discourse/models/topic-details.js.es6 b/app/assets/javascripts/discourse/models/topic-details.js.es6
index c86b93f2ba0..01b31d5ddd1 100644
--- a/app/assets/javascripts/discourse/models/topic-details.js.es6
+++ b/app/assets/javascripts/discourse/models/topic-details.js.es6
@@ -1,4 +1,6 @@
import { ajax } from "discourse/lib/ajax";
+import computed from "ember-addons/ember-computed-decorators";
+
/**
A model representing a Topic's details that aren't always present, such as a list of participants.
When showing topics in lists and such this information should not be required.
@@ -29,15 +31,15 @@ const TopicDetails = RestModel.extend({
this.set("loaded", true);
},
- notificationReasonText: function() {
- let level = this.get("notification_level");
+ @computed("notification_level", "notifications_reason_id")
+ notificationReasonText(level, reason) {
if (typeof level !== "number") {
level = 1;
}
let localeString = `topic.notifications.reasons.${level}`;
- if (typeof this.get("notifications_reason_id") === "number") {
- const tmp = localeString + "_" + this.get("notifications_reason_id");
+ if (typeof reason === "number") {
+ const tmp = localeString + "_" + reason;
// some sane protection for missing translations of edge cases
if (I18n.lookup(tmp)) {
localeString = tmp;
@@ -55,7 +57,7 @@ const TopicDetails = RestModel.extend({
basePath: Discourse.BaseUri
});
}
- }.property("notification_level", "notifications_reason_id"),
+ },
updateNotifications(v) {
this.set("notification_level", v);
diff --git a/app/assets/javascripts/discourse/models/user-action-stat.js.es6 b/app/assets/javascripts/discourse/models/user-action-stat.js.es6
index 089225b2a4e..fd531cde9ad 100644
--- a/app/assets/javascripts/discourse/models/user-action-stat.js.es6
+++ b/app/assets/javascripts/discourse/models/user-action-stat.js.es6
@@ -1,23 +1,24 @@
import RestModel from "discourse/models/rest";
import UserAction from "discourse/models/user-action";
import { i18n } from "discourse/lib/computed";
+import computed from "ember-addons/ember-computed-decorators";
export default RestModel.extend({
- isPM: function() {
- const actionType = this.get("action_type");
+ @computed("action_type")
+ isPM(actionType) {
return (
actionType === UserAction.TYPES.messages_sent ||
actionType === UserAction.TYPES.messages_received
);
- }.property("action_type"),
+ },
description: i18n("action_type", "user_action_groups.%@"),
- isResponse: function() {
- const actionType = this.get("action_type");
+ @computed("action_type")
+ isResponse(actionType) {
return (
actionType === UserAction.TYPES.replies ||
actionType === UserAction.TYPES.quotes
);
- }.property("action_type")
+ }
});
diff --git a/app/assets/javascripts/discourse/models/user-action.js.es6 b/app/assets/javascripts/discourse/models/user-action.js.es6
index 8f2d6986a01..db3a357530a 100644
--- a/app/assets/javascripts/discourse/models/user-action.js.es6
+++ b/app/assets/javascripts/discourse/models/user-action.js.es6
@@ -164,16 +164,7 @@ const UserAction = RestModel.extend({
}
},
- children: function() {
- const g = this.get("childGroups");
- let rval = [];
- if (g) {
- rval = [g.likes, g.stars, g.edits, g.bookmarks].filter(function(i) {
- return i.get("items") && i.get("items").length > 0;
- });
- }
- return rval;
- }.property(
+ @computed(
"childGroups",
"childGroups.likes.items",
"childGroups.likes.items.[]",
@@ -183,7 +174,17 @@ const UserAction = RestModel.extend({
"childGroups.edits.items.[]",
"childGroups.bookmarks.items",
"childGroups.bookmarks.items.[]"
- ),
+ )
+ children() {
+ const g = this.get("childGroups");
+ let rval = [];
+ if (g) {
+ rval = [g.likes, g.stars, g.edits, g.bookmarks].filter(function(i) {
+ return i.get("items") && i.get("items").length > 0;
+ });
+ }
+ return rval;
+ },
switchToActing() {
this.setProperties({
diff --git a/app/assets/javascripts/discourse/models/user-badge.js.es6 b/app/assets/javascripts/discourse/models/user-badge.js.es6
index d746efc2b80..7022a1d8fbe 100644
--- a/app/assets/javascripts/discourse/models/user-badge.js.es6
+++ b/app/assets/javascripts/discourse/models/user-badge.js.es6
@@ -1,12 +1,14 @@
import { ajax } from "discourse/lib/ajax";
import Badge from "discourse/models/badge";
+import computed from "ember-addons/ember-computed-decorators";
const UserBadge = Discourse.Model.extend({
+ @computed
postUrl: function() {
if (this.get("topic_title")) {
return "/t/-/" + this.get("topic_id") + "/" + this.get("post_number");
}
- }.property(), // avoid the extra bindings for now
+ }, // avoid the extra bindings for now
revoke() {
return ajax("/user_badges/" + this.get("id"), {
diff --git a/app/assets/javascripts/discourse/models/user-stream.js.es6 b/app/assets/javascripts/discourse/models/user-stream.js.es6
index bca6e7c0bc6..ee2efcd1c05 100644
--- a/app/assets/javascripts/discourse/models/user-stream.js.es6
+++ b/app/assets/javascripts/discourse/models/user-stream.js.es6
@@ -3,6 +3,7 @@ import { url } from "discourse/lib/computed";
import RestModel from "discourse/models/rest";
import UserAction from "discourse/models/user-action";
import { emojiUnescape } from "discourse/lib/text";
+import computed from "ember-addons/ember-computed-decorators";
export default RestModel.extend({
loaded: false,
@@ -11,8 +12,8 @@ export default RestModel.extend({
this.setProperties({ itemsLoaded: 0, content: [] });
}.on("init"),
- filterParam: function() {
- const filter = this.get("filter");
+ @computed("filter")
+ filterParam(filter) {
if (filter === Discourse.UserAction.TYPES.replies) {
return [UserAction.TYPES.replies, UserAction.TYPES.quotes].join(",");
}
@@ -22,7 +23,7 @@ export default RestModel.extend({
}
return filter;
- }.property("filter"),
+ },
baseUrl: url(
"itemsLoaded",
@@ -45,9 +46,10 @@ export default RestModel.extend({
return this.findItems();
},
- noContent: function() {
+ @computed("loaded", "content.[]")
+ noContent() {
return this.get("loaded") && this.get("content").length === 0;
- }.property("loaded", "content.[]"),
+ },
remove(userAction) {
// 1) remove the user action from the child groups
diff --git a/app/assets/javascripts/discourse/raw-views/list/visited-line.js.es6 b/app/assets/javascripts/discourse/raw-views/list/visited-line.js.es6
index 0f928e3f3a7..b276022a1d6 100644
--- a/app/assets/javascripts/discourse/raw-views/list/visited-line.js.es6
+++ b/app/assets/javascripts/discourse/raw-views/list/visited-line.js.es6
@@ -1,5 +1,8 @@
+import computed from "ember-addons/ember-computed-decorators";
+
export default Ember.Object.extend({
+ @computed
isLastVisited: function() {
return this.get("lastVisitedTopic") === this.get("topic");
- }.property()
+ }
});
diff --git a/app/assets/javascripts/discourse/templates/components/basic-topic-list.hbs b/app/assets/javascripts/discourse/templates/components/basic-topic-list.hbs
index d1d105121ef..727715048ee 100644
--- a/app/assets/javascripts/discourse/templates/components/basic-topic-list.hbs
+++ b/app/assets/javascripts/discourse/templates/components/basic-topic-list.hbs
@@ -17,7 +17,7 @@
bulkSelectEnabled=bulkSelectEnabled
canBulkSelect=canBulkSelect
selected=selected
- skipHeader=skipHeader
+ skipHeader=site.mobileView
tagsForUser=tagsForUser}}
{{else}}
{{#unless loadingMore}}
diff --git a/app/assets/javascripts/discourse/templates/components/topic-list.hbs b/app/assets/javascripts/discourse/templates/components/topic-list.hbs
index 46e05f4e4d6..cb9d4ab320e 100644
--- a/app/assets/javascripts/discourse/templates/components/topic-list.hbs
+++ b/app/assets/javascripts/discourse/templates/components/topic-list.hbs
@@ -1,4 +1,4 @@
-{{#unless skipHeader}}
+{{#unless site.mobileView}}
{{raw "topic-list-header"
canBulkSelect=canBulkSelect