mirror of
https://github.com/discourse/discourse.git
synced 2024-11-24 01:22:36 +08:00
REFACTOR: topic model (#7020)
This commit is contained in:
parent
15fd875855
commit
8a4cd15e46
|
@ -1,30 +1,34 @@
|
||||||
import { ajax } from "discourse/lib/ajax";
|
import { ajax } from "discourse/lib/ajax";
|
||||||
import { flushMap } from "discourse/models/store";
|
import { flushMap } from "discourse/models/store";
|
||||||
import RestModel from "discourse/models/rest";
|
import RestModel from "discourse/models/rest";
|
||||||
import { propertyEqual } from "discourse/lib/computed";
|
import { propertyEqual, fmt } from "discourse/lib/computed";
|
||||||
import { longDate } from "discourse/lib/formatter";
|
import { longDate } from "discourse/lib/formatter";
|
||||||
import { isRTL } from "discourse/lib/text-direction";
|
import { isRTL } from "discourse/lib/text-direction";
|
||||||
import computed from "ember-addons/ember-computed-decorators";
|
|
||||||
import ActionSummary from "discourse/models/action-summary";
|
import ActionSummary from "discourse/models/action-summary";
|
||||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
import { censor } from "pretty-text/censored-words";
|
import { censor } from "pretty-text/censored-words";
|
||||||
import { emojiUnescape } from "discourse/lib/text";
|
import { emojiUnescape } from "discourse/lib/text";
|
||||||
import PreloadStore from "preload-store";
|
import PreloadStore from "preload-store";
|
||||||
import { userPath } from "discourse/lib/url";
|
import { userPath } from "discourse/lib/url";
|
||||||
|
import {
|
||||||
|
default as computed,
|
||||||
|
observes,
|
||||||
|
on
|
||||||
|
} from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
export function loadTopicView(topic, args) {
|
export function loadTopicView(topic, args) {
|
||||||
const topicId = topic.get("id");
|
const topicId = topic.get("id");
|
||||||
const data = _.merge({}, args);
|
const data = _.merge({}, args);
|
||||||
const url = Discourse.getURL("/t/") + topicId;
|
const url = `${Discourse.getURL("/t/")}${topicId}`;
|
||||||
const jsonUrl = (data.nearPost ? `${url}/${data.nearPost}` : url) + ".json";
|
const jsonUrl = (data.nearPost ? `${url}/${data.nearPost}` : url) + ".json";
|
||||||
|
|
||||||
delete data.nearPost;
|
delete data.nearPost;
|
||||||
delete data.__type;
|
delete data.__type;
|
||||||
delete data.store;
|
delete data.store;
|
||||||
|
|
||||||
return PreloadStore.getAndRemove(`topic_${topicId}`, () => {
|
return PreloadStore.getAndRemove(`topic_${topicId}`, () =>
|
||||||
return ajax(jsonUrl, { data });
|
ajax(jsonUrl, { data })
|
||||||
}).then(json => {
|
).then(json => {
|
||||||
topic.updateFromJson(json);
|
topic.updateFromJson(json);
|
||||||
return json;
|
return json;
|
||||||
});
|
});
|
||||||
|
@ -101,44 +105,44 @@ const Topic = RestModel.extend({
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Discourse.SiteSettings.support_mixed_text_direction) {
|
if (Discourse.SiteSettings.support_mixed_text_direction) {
|
||||||
let titleDir = isRTL(title) ? "rtl" : "ltr";
|
const titleDir = isRTL(title) ? "rtl" : "ltr";
|
||||||
return `<span dir="${titleDir}">${fancyTitle}</span>`;
|
return `<span dir="${titleDir}">${fancyTitle}</span>`;
|
||||||
}
|
}
|
||||||
return fancyTitle;
|
return fancyTitle;
|
||||||
},
|
},
|
||||||
|
|
||||||
// returns createdAt if there's no bumped date
|
// returns createdAt if there's no bumped date
|
||||||
bumpedAt: function() {
|
@computed("bumped_at", "createdAt")
|
||||||
const bumpedAt = this.get("bumped_at");
|
bumpedAt(bumped_at, createdAt) {
|
||||||
if (bumpedAt) {
|
if (bumped_at) {
|
||||||
return new Date(bumpedAt);
|
return new Date(bumped_at);
|
||||||
} else {
|
} else {
|
||||||
return this.get("createdAt");
|
return createdAt;
|
||||||
}
|
}
|
||||||
}.property("bumped_at", "createdAt"),
|
},
|
||||||
|
|
||||||
bumpedAtTitle: function() {
|
@computed("bumpedAt", "createdAt")
|
||||||
return (
|
bumpedAtTitle(bumpedAt, createdAt) {
|
||||||
I18n.t("first_post") +
|
const firstPost = I18n.t("first_post");
|
||||||
": " +
|
const lastPost = I18n.t("last_post");
|
||||||
longDate(this.get("createdAt")) +
|
const createdAtDate = longDate(createdAt);
|
||||||
"\n" +
|
const bumpedAtDate = longDate(bumpedAt);
|
||||||
I18n.t("last_post") +
|
|
||||||
": " +
|
|
||||||
longDate(this.get("bumpedAt"))
|
|
||||||
);
|
|
||||||
}.property("bumpedAt"),
|
|
||||||
|
|
||||||
createdAt: function() {
|
return `${firstPost}: ${createdAtDate}\n${lastPost}: ${bumpedAtDate}`;
|
||||||
return new Date(this.get("created_at"));
|
},
|
||||||
}.property("created_at"),
|
|
||||||
|
|
||||||
postStream: function() {
|
@computed("created_at")
|
||||||
|
createdAt(created_at) {
|
||||||
|
return new Date(created_at);
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed
|
||||||
|
postStream() {
|
||||||
return this.store.createRecord("postStream", {
|
return this.store.createRecord("postStream", {
|
||||||
id: this.get("id"),
|
id: this.get("id"),
|
||||||
topic: this
|
topic: this
|
||||||
});
|
});
|
||||||
}.property(),
|
},
|
||||||
|
|
||||||
@computed("tags")
|
@computed("tags")
|
||||||
visibleListTags(tags) {
|
visibleListTags(tags) {
|
||||||
|
@ -165,9 +169,7 @@ const Topic = RestModel.extend({
|
||||||
|
|
||||||
return this.set(
|
return this.set(
|
||||||
"related_messages",
|
"related_messages",
|
||||||
relatedMessages.map(st => {
|
relatedMessages.map(st => store.createRecord("topic", st))
|
||||||
return store.createRecord("topic", st);
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -179,115 +181,116 @@ const Topic = RestModel.extend({
|
||||||
|
|
||||||
return this.set(
|
return this.set(
|
||||||
"suggested_topics",
|
"suggested_topics",
|
||||||
suggestedTopics.map(st => {
|
suggestedTopics.map(st => store.createRecord("topic", st))
|
||||||
return store.createRecord("topic", st);
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
replyCount: function() {
|
@computed("posts_count")
|
||||||
return this.get("posts_count") - 1;
|
replyCount(postsCount) {
|
||||||
}.property("posts_count"),
|
return postsCount - 1;
|
||||||
|
},
|
||||||
|
|
||||||
details: function() {
|
@computed
|
||||||
|
details() {
|
||||||
return this.store.createRecord("topicDetails", {
|
return this.store.createRecord("topicDetails", {
|
||||||
id: this.get("id"),
|
id: this.get("id"),
|
||||||
topic: this
|
topic: this
|
||||||
});
|
});
|
||||||
}.property(),
|
},
|
||||||
|
|
||||||
invisible: Ember.computed.not("visible"),
|
invisible: Ember.computed.not("visible"),
|
||||||
deleted: Ember.computed.notEmpty("deleted_at"),
|
deleted: Ember.computed.notEmpty("deleted_at"),
|
||||||
|
|
||||||
searchContext: function() {
|
@computed("id")
|
||||||
return { type: "topic", id: this.get("id") };
|
searchContext(id) {
|
||||||
}.property("id"),
|
return { type: "topic", id };
|
||||||
|
},
|
||||||
|
|
||||||
_categoryIdChanged: function() {
|
@on("init")
|
||||||
|
@observes("category_id")
|
||||||
|
_categoryIdChanged() {
|
||||||
this.set("category", Discourse.Category.findById(this.get("category_id")));
|
this.set("category", Discourse.Category.findById(this.get("category_id")));
|
||||||
}
|
},
|
||||||
.observes("category_id")
|
|
||||||
.on("init"),
|
|
||||||
|
|
||||||
_categoryNameChanged: function() {
|
@observes("categoryName")
|
||||||
|
_categoryNameChanged() {
|
||||||
const categoryName = this.get("categoryName");
|
const categoryName = this.get("categoryName");
|
||||||
let category;
|
let category;
|
||||||
if (categoryName) {
|
if (categoryName) {
|
||||||
category = this.site.get("categories").findBy("name", categoryName);
|
category = this.site.get("categories").findBy("name", categoryName);
|
||||||
}
|
}
|
||||||
this.set("category", category);
|
this.set("category", category);
|
||||||
}.observes("categoryName"),
|
|
||||||
|
|
||||||
categoryClass: function() {
|
|
||||||
return "category-" + this.get("category.fullSlug");
|
|
||||||
}.property("category.fullSlug"),
|
|
||||||
|
|
||||||
shareUrl: function() {
|
|
||||||
const user = Discourse.User.current();
|
|
||||||
return this.get("url") + (user ? "?u=" + user.get("username_lower") : "");
|
|
||||||
}.property("url"),
|
|
||||||
|
|
||||||
@computed("url")
|
|
||||||
printUrl(url) {
|
|
||||||
return url + "/print";
|
|
||||||
},
|
},
|
||||||
|
|
||||||
url: function() {
|
categoryClass: fmt("category.fullSlug", "category-%@"),
|
||||||
let slug = this.get("slug") || "";
|
|
||||||
|
@computed("url")
|
||||||
|
shareUrl(url) {
|
||||||
|
const user = Discourse.User.current();
|
||||||
|
const userQueryString = user ? `?u=${user.get("username_lower")}` : "";
|
||||||
|
return `${url}${userQueryString}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
printUrl: fmt("url", "%@/print"),
|
||||||
|
|
||||||
|
@computed("id", "slug")
|
||||||
|
url(id, slug) {
|
||||||
|
slug = slug || "";
|
||||||
if (slug.trim().length === 0) {
|
if (slug.trim().length === 0) {
|
||||||
slug = "topic";
|
slug = "topic";
|
||||||
}
|
}
|
||||||
return Discourse.getURL("/t/") + slug + "/" + this.get("id");
|
return `${Discourse.getURL("/t/")}${slug}/${id}`;
|
||||||
}.property("id", "slug"),
|
},
|
||||||
|
|
||||||
// Helper to build a Url with a post number
|
// Helper to build a Url with a post number
|
||||||
urlForPostNumber(postNumber) {
|
urlForPostNumber(postNumber) {
|
||||||
let url = this.get("url");
|
let url = this.get("url");
|
||||||
if (postNumber && postNumber > 0) {
|
if (postNumber && postNumber > 0) {
|
||||||
url += "/" + postNumber;
|
url += `/${postNumber}`;
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
},
|
},
|
||||||
|
|
||||||
totalUnread: function() {
|
@computed("new_posts", "unread")
|
||||||
const count = (this.get("unread") || 0) + (this.get("new_posts") || 0);
|
totalUnread(newPosts, unread) {
|
||||||
|
const count = (unread || 0) + (newPosts || 0);
|
||||||
return count > 0 ? count : null;
|
return count > 0 ? count : null;
|
||||||
}.property("new_posts", "unread"),
|
},
|
||||||
|
|
||||||
lastReadUrl: function() {
|
@computed("last_read_post_number", "url")
|
||||||
return this.urlForPostNumber(this.get("last_read_post_number"));
|
lastReadUrl(lastReadPostNumber) {
|
||||||
}.property("url", "last_read_post_number"),
|
return this.urlForPostNumber(lastReadPostNumber);
|
||||||
|
},
|
||||||
|
|
||||||
lastUnreadUrl: function() {
|
@computed("last_read_post_number", "highest_post_number", "url")
|
||||||
const highest = this.get("highest_post_number");
|
lastUnreadUrl(lastReadPostNumber, highestPostNumber) {
|
||||||
const lastRead = this.get("last_read_post_number");
|
if (highestPostNumber <= lastReadPostNumber) {
|
||||||
|
|
||||||
if (highest <= lastRead) {
|
|
||||||
if (this.get("category.navigate_to_first_post_after_read")) {
|
if (this.get("category.navigate_to_first_post_after_read")) {
|
||||||
return this.urlForPostNumber(1);
|
return this.urlForPostNumber(1);
|
||||||
} else {
|
} else {
|
||||||
return this.urlForPostNumber(lastRead + 1);
|
return this.urlForPostNumber(lastReadPostNumber + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return this.urlForPostNumber(lastRead + 1);
|
return this.urlForPostNumber(lastReadPostNumber + 1);
|
||||||
}
|
}
|
||||||
}.property("url", "last_read_post_number", "highest_post_number"),
|
},
|
||||||
|
|
||||||
lastPostUrl: function() {
|
@computed("highest_post_number", "url")
|
||||||
return this.urlForPostNumber(this.get("highest_post_number"));
|
lastPostUrl(highestPostNumber) {
|
||||||
}.property("url", "highest_post_number"),
|
return this.urlForPostNumber(highestPostNumber);
|
||||||
|
},
|
||||||
|
|
||||||
firstPostUrl: function() {
|
@computed("url")
|
||||||
|
firstPostUrl() {
|
||||||
return this.urlForPostNumber(1);
|
return this.urlForPostNumber(1);
|
||||||
}.property("url"),
|
},
|
||||||
|
|
||||||
summaryUrl: function() {
|
@computed("url")
|
||||||
return (
|
summaryUrl() {
|
||||||
this.urlForPostNumber(1) +
|
const summaryQueryString = this.get("has_summary") ? "?filter=summary" : "";
|
||||||
(this.get("has_summary") ? "?filter=summary" : "")
|
return `${this.urlForPostNumber(1)}${summaryQueryString}`;
|
||||||
);
|
},
|
||||||
}.property("url"),
|
|
||||||
|
|
||||||
@computed("last_poster.username")
|
@computed("last_poster.username")
|
||||||
lastPosterUrl(username) {
|
lastPosterUrl(username) {
|
||||||
|
@ -297,39 +300,40 @@ const Topic = RestModel.extend({
|
||||||
// The amount of new posts to display. It might be different than what the server
|
// The amount of new posts to display. It might be different than what the server
|
||||||
// tells us if we are still asynchronously flushing our "recently read" data.
|
// tells us if we are still asynchronously flushing our "recently read" data.
|
||||||
// So take what the browser has seen into consideration.
|
// So take what the browser has seen into consideration.
|
||||||
displayNewPosts: function() {
|
@computed("new_posts", "id")
|
||||||
const highestSeen = Discourse.Session.currentProp("highestSeenByTopic")[
|
displayNewPosts(newPosts, id) {
|
||||||
this.get("id")
|
const highestSeen = Discourse.Session.currentProp("highestSeenByTopic")[id];
|
||||||
];
|
|
||||||
if (highestSeen) {
|
if (highestSeen) {
|
||||||
let delta = highestSeen - this.get("last_read_post_number");
|
const delta = highestSeen - this.get("last_read_post_number");
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
let result = this.get("new_posts") - delta;
|
let result = newPosts - delta;
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.get("new_posts");
|
return newPosts;
|
||||||
}.property("new_posts", "id"),
|
},
|
||||||
|
|
||||||
viewsHeat: function() {
|
@computed("views")
|
||||||
const v = this.get("views");
|
viewsHeat(v) {
|
||||||
if (v >= Discourse.SiteSettings.topic_views_heat_high)
|
if (v >= Discourse.SiteSettings.topic_views_heat_high) {
|
||||||
return "heatmap-high";
|
return "heatmap-high";
|
||||||
if (v >= Discourse.SiteSettings.topic_views_heat_medium)
|
}
|
||||||
|
if (v >= Discourse.SiteSettings.topic_views_heat_medium) {
|
||||||
return "heatmap-med";
|
return "heatmap-med";
|
||||||
if (v >= Discourse.SiteSettings.topic_views_heat_low) return "heatmap-low";
|
}
|
||||||
|
if (v >= Discourse.SiteSettings.topic_views_heat_low) {
|
||||||
|
return "heatmap-low";
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}.property("views"),
|
},
|
||||||
|
|
||||||
archetypeObject: function() {
|
@computed("archetype")
|
||||||
return Discourse.Site.currentProp("archetypes").findBy(
|
archetypeObject(archetype) {
|
||||||
"id",
|
return Discourse.Site.currentProp("archetypes").findBy("id", archetype);
|
||||||
this.get("archetype")
|
},
|
||||||
);
|
|
||||||
}.property("archetype"),
|
|
||||||
|
|
||||||
isPrivateMessage: Ember.computed.equal("archetype", "private_message"),
|
isPrivateMessage: Ember.computed.equal("archetype", "private_message"),
|
||||||
isBanner: Ember.computed.equal("archetype", "banner"),
|
isBanner: Ember.computed.equal("archetype", "banner"),
|
||||||
|
@ -343,32 +347,26 @@ const Topic = RestModel.extend({
|
||||||
if (property === "closed") {
|
if (property === "closed") {
|
||||||
this.incrementProperty("posts_count");
|
this.incrementProperty("posts_count");
|
||||||
}
|
}
|
||||||
return ajax(this.get("url") + "/status", {
|
return ajax(`${this.get("url")}/status`, {
|
||||||
type: "PUT",
|
type: "PUT",
|
||||||
data: {
|
data: {
|
||||||
status: property,
|
status: property,
|
||||||
enabled: !!value,
|
enabled: !!value,
|
||||||
until: until
|
until
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
makeBanner() {
|
makeBanner() {
|
||||||
const self = this;
|
return ajax(`/t/${this.get("id")}/make-banner`, { type: "PUT" }).then(() =>
|
||||||
return ajax("/t/" + this.get("id") + "/make-banner", { type: "PUT" }).then(
|
this.set("archetype", "banner")
|
||||||
function() {
|
|
||||||
self.set("archetype", "banner");
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
removeBanner() {
|
removeBanner() {
|
||||||
const self = this;
|
return ajax(`/t/${this.get("id")}/remove-banner`, {
|
||||||
return ajax("/t/" + this.get("id") + "/remove-banner", {
|
|
||||||
type: "PUT"
|
type: "PUT"
|
||||||
}).then(function() {
|
}).then(() => this.set("archetype", "regular"));
|
||||||
self.set("archetype", "regular");
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleBookmark() {
|
toggleBookmark() {
|
||||||
|
@ -432,23 +430,23 @@ const Topic = RestModel.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
createGroupInvite(group) {
|
createGroupInvite(group) {
|
||||||
return ajax("/t/" + this.get("id") + "/invite-group", {
|
return ajax(`/t/${this.get("id")}/invite-group`, {
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: { group }
|
data: { group }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
createInvite(user, group_names, custom_message) {
|
createInvite(user, group_names, custom_message) {
|
||||||
return ajax("/t/" + this.get("id") + "/invite", {
|
return ajax(`/t/${this.get("id")}/invite`, {
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: { user, group_names, custom_message }
|
data: { user, group_names, custom_message }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
generateInviteLink: function(email, groupNames, topicId) {
|
generateInviteLink(email, groupNames, topicId) {
|
||||||
return ajax("/invites/link", {
|
return ajax("/invites/link", {
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: { email: email, group_names: groupNames, topic_id: topicId }
|
data: { email, group_names: groupNames, topic_id: topicId }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -492,28 +490,25 @@ const Topic = RestModel.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
return ajax(`/t/${this.get("id")}`, { type: "GET" }).then(topic_json => {
|
return ajax(`/t/${this.get("id")}`, { type: "GET" }).then(topic_json =>
|
||||||
this.updateFromJson(topic_json);
|
this.updateFromJson(topic_json)
|
||||||
});
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
isPinnedUncategorized: function() {
|
isPinnedUncategorized: Ember.computed.and(
|
||||||
return this.get("pinned") && this.get("category.isUncategorizedCategory");
|
"pinned",
|
||||||
}.property("pinned", "category.isUncategorizedCategory"),
|
"category.isUncategorizedCategory"
|
||||||
|
),
|
||||||
|
|
||||||
clearPin() {
|
clearPin() {
|
||||||
const topic = this;
|
|
||||||
|
|
||||||
// Clear the pin optimistically from the object
|
// Clear the pin optimistically from the object
|
||||||
topic.set("pinned", false);
|
this.setProperties({ pinned: false, unpinned: true });
|
||||||
topic.set("unpinned", true);
|
|
||||||
|
|
||||||
ajax("/t/" + this.get("id") + "/clear-pin", {
|
ajax(`/t/${this.get("id")}/clear-pin`, {
|
||||||
type: "PUT"
|
type: "PUT"
|
||||||
}).then(null, function() {
|
}).then(null, () => {
|
||||||
// On error, put the pin back
|
// On error, put the pin back
|
||||||
topic.set("pinned", true);
|
this.setProperties({ pinned: true, unpinned: false });
|
||||||
topic.set("unpinned", false);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -526,18 +521,14 @@ const Topic = RestModel.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
rePin() {
|
rePin() {
|
||||||
const topic = this;
|
|
||||||
|
|
||||||
// Clear the pin optimistically from the object
|
// Clear the pin optimistically from the object
|
||||||
topic.set("pinned", true);
|
this.setProperties({ pinned: true, unpinned: false });
|
||||||
topic.set("unpinned", false);
|
|
||||||
|
|
||||||
ajax("/t/" + this.get("id") + "/re-pin", {
|
ajax(`/t/${this.get("id")}/re-pin`, {
|
||||||
type: "PUT"
|
type: "PUT"
|
||||||
}).then(null, function() {
|
}).then(null, () => {
|
||||||
// On error, put the pin back
|
// On error, put the pin back
|
||||||
topic.set("pinned", true);
|
this.setProperties({ pinned: true, unpinned: false });
|
||||||
topic.set("unpinned", false);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -548,17 +539,19 @@ const Topic = RestModel.extend({
|
||||||
|
|
||||||
hasExcerpt: Ember.computed.notEmpty("excerpt"),
|
hasExcerpt: Ember.computed.notEmpty("excerpt"),
|
||||||
|
|
||||||
excerptTruncated: function() {
|
@computed("excerpt")
|
||||||
const e = this.get("excerpt");
|
excerptTruncated(excerpt) {
|
||||||
return e && e.substr(e.length - 8, 8) === "…";
|
return excerpt && excerpt.substr(excerpt.length - 8, 8) === "…";
|
||||||
}.property("excerpt"),
|
},
|
||||||
|
|
||||||
readLastPost: propertyEqual("last_read_post_number", "highest_post_number"),
|
readLastPost: propertyEqual("last_read_post_number", "highest_post_number"),
|
||||||
canClearPin: Ember.computed.and("pinned", "readLastPost"),
|
canClearPin: Ember.computed.and("pinned", "readLastPost"),
|
||||||
|
|
||||||
archiveMessage() {
|
archiveMessage() {
|
||||||
this.set("archiving", true);
|
this.set("archiving", true);
|
||||||
var promise = ajax(`/t/${this.get("id")}/archive-message`, { type: "PUT" });
|
const promise = ajax(`/t/${this.get("id")}/archive-message`, {
|
||||||
|
type: "PUT"
|
||||||
|
});
|
||||||
|
|
||||||
promise
|
promise
|
||||||
.then(msg => {
|
.then(msg => {
|
||||||
|
@ -574,7 +567,7 @@ const Topic = RestModel.extend({
|
||||||
|
|
||||||
moveToInbox() {
|
moveToInbox() {
|
||||||
this.set("archiving", true);
|
this.set("archiving", true);
|
||||||
var promise = ajax(`/t/${this.get("id")}/move-to-inbox`, { type: "PUT" });
|
const promise = ajax(`/t/${this.get("id")}/move-to-inbox`, { type: "PUT" });
|
||||||
|
|
||||||
promise
|
promise
|
||||||
.then(msg => {
|
.then(msg => {
|
||||||
|
@ -593,9 +586,7 @@ const Topic = RestModel.extend({
|
||||||
type: "PUT",
|
type: "PUT",
|
||||||
data: this.getProperties("destination_category_id")
|
data: this.getProperties("destination_category_id")
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => this.set("destination_category_id", null))
|
||||||
this.set("destination_category_id", null);
|
|
||||||
})
|
|
||||||
.catch(popupAjaxError);
|
.catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -609,9 +600,7 @@ const Topic = RestModel.extend({
|
||||||
|
|
||||||
convertTopic(type) {
|
convertTopic(type) {
|
||||||
return ajax(`/t/${this.get("id")}/convert-topic/${type}`, { type: "PUT" })
|
return ajax(`/t/${this.get("id")}/convert-topic/${type}`, { type: "PUT" })
|
||||||
.then(() => {
|
.then(() => window.location.reload())
|
||||||
window.location.reload();
|
|
||||||
})
|
|
||||||
.catch(popupAjaxError);
|
.catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -633,7 +622,7 @@ Topic.reopenClass({
|
||||||
createActionSummary(result) {
|
createActionSummary(result) {
|
||||||
if (result.actions_summary) {
|
if (result.actions_summary) {
|
||||||
const lookup = Ember.Object.create();
|
const lookup = Ember.Object.create();
|
||||||
result.actions_summary = result.actions_summary.map(function(a) {
|
result.actions_summary = result.actions_summary.map(a => {
|
||||||
a.post = result;
|
a.post = result;
|
||||||
a.actionType = Discourse.Site.current().postActionTypeById(a.id);
|
a.actionType = Discourse.Site.current().postActionTypeById(a.id);
|
||||||
const actionSummary = ActionSummary.create(a);
|
const actionSummary = ActionSummary.create(a);
|
||||||
|
@ -664,13 +653,11 @@ Topic.reopenClass({
|
||||||
Object.keys(props).forEach(function(k) {
|
Object.keys(props).forEach(function(k) {
|
||||||
const v = props[k];
|
const v = props[k];
|
||||||
if (v instanceof Array && v.length === 0) {
|
if (v instanceof Array && v.length === 0) {
|
||||||
props[k + "_empty_array"] = true;
|
props[`${k}_empty_array`] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return ajax(topic.get("url"), { type: "PUT", data: props }).then(function(
|
return ajax(topic.get("url"), { type: "PUT", data: props }).then(result => {
|
||||||
result
|
|
||||||
) {
|
|
||||||
// The title can be cleaned up server side
|
// The title can be cleaned up server side
|
||||||
props.title = result.basic_topic.title;
|
props.title = result.basic_topic.title;
|
||||||
props.fancy_title = result.basic_topic.fancy_title;
|
props.fancy_title = result.basic_topic.fancy_title;
|
||||||
|
@ -688,7 +675,7 @@ Topic.reopenClass({
|
||||||
find(topicId, opts) {
|
find(topicId, opts) {
|
||||||
let url = Discourse.getURL("/t/") + topicId;
|
let url = Discourse.getURL("/t/") + topicId;
|
||||||
if (opts.nearPost) {
|
if (opts.nearPost) {
|
||||||
url += "/" + opts.nearPost;
|
url += `/${opts.nearPost}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = {};
|
const data = {};
|
||||||
|
@ -716,14 +703,14 @@ Topic.reopenClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the preload store. If not, load it via JSON
|
// Check the preload store. If not, load it via JSON
|
||||||
return ajax(url + ".json", { data: data });
|
return ajax(`${url}.json`, { data });
|
||||||
},
|
},
|
||||||
|
|
||||||
changeOwners(topicId, opts) {
|
changeOwners(topicId, opts) {
|
||||||
const promise = ajax("/t/" + topicId + "/change-owner", {
|
const promise = ajax(`/t/${topicId}/change-owner`, {
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: opts
|
data: opts
|
||||||
}).then(function(result) {
|
}).then(result => {
|
||||||
if (result.success) return result;
|
if (result.success) return result;
|
||||||
promise.reject(new Error("error changing ownership of posts"));
|
promise.reject(new Error("error changing ownership of posts"));
|
||||||
});
|
});
|
||||||
|
@ -731,10 +718,10 @@ Topic.reopenClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
changeTimestamp(topicId, timestamp) {
|
changeTimestamp(topicId, timestamp) {
|
||||||
const promise = ajax("/t/" + topicId + "/change-timestamp", {
|
const promise = ajax(`/t/${topicId}/change-timestamp`, {
|
||||||
type: "PUT",
|
type: "PUT",
|
||||||
data: { timestamp: timestamp }
|
data: { timestamp }
|
||||||
}).then(function(result) {
|
}).then(result => {
|
||||||
if (result.success) return result;
|
if (result.success) return result;
|
||||||
promise.reject(new Error("error updating timestamp of topic"));
|
promise.reject(new Error("error updating timestamp of topic"));
|
||||||
});
|
});
|
||||||
|
@ -745,20 +732,18 @@ Topic.reopenClass({
|
||||||
return ajax("/topics/bulk", {
|
return ajax("/topics/bulk", {
|
||||||
type: "PUT",
|
type: "PUT",
|
||||||
data: {
|
data: {
|
||||||
topic_ids: topics.map(function(t) {
|
topic_ids: topics.map(t => t.get("id")),
|
||||||
return t.get("id");
|
operation
|
||||||
}),
|
|
||||||
operation: operation
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
bulkOperationByFilter(filter, operation, categoryId) {
|
bulkOperationByFilter(filter, operation, categoryId) {
|
||||||
const data = { filter: filter, operation: operation };
|
const data = { filter, operation };
|
||||||
if (categoryId) data["category_id"] = categoryId;
|
if (categoryId) data.category_id = categoryId;
|
||||||
return ajax("/topics/bulk", {
|
return ajax("/topics/bulk", {
|
||||||
type: "PUT",
|
type: "PUT",
|
||||||
data: data
|
data
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -767,7 +752,7 @@ Topic.reopenClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
idForSlug(slug) {
|
idForSlug(slug) {
|
||||||
return ajax("/t/id_for/" + slug);
|
return ajax(`/t/id_for/${slug}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -781,13 +766,13 @@ function moveResult(result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function movePosts(topicId, data) {
|
export function movePosts(topicId, data) {
|
||||||
return ajax("/t/" + topicId + "/move-posts", { type: "POST", data }).then(
|
return ajax(`/t/${topicId}/move-posts`, { type: "POST", data }).then(
|
||||||
moveResult
|
moveResult
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mergeTopic(topicId, data) {
|
export function mergeTopic(topicId, data) {
|
||||||
return ajax("/t/" + topicId + "/merge-topic", { type: "POST", data }).then(
|
return ajax(`/t/${topicId}/merge-topic`, { type: "POST", data }).then(
|
||||||
moveResult
|
moveResult
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user