mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 16:13:38 +08:00
DEV: Update topic
and post
models to native class syntax (#25612)
This commit was created with a combination of the ember-native-class-codemod and manual cleanup
This commit is contained in:
parent
6c597b648b
commit
a3ef9e92eb
|
@ -18,8 +18,99 @@ import User from "discourse/models/user";
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
const Post = RestModel.extend({
|
||||
customShare: null,
|
||||
export default class Post extends RestModel {
|
||||
static munge(json) {
|
||||
if (json.actions_summary) {
|
||||
const lookup = EmberObject.create();
|
||||
|
||||
// this area should be optimized, it is creating way too many objects per post
|
||||
json.actions_summary = json.actions_summary.map((a) => {
|
||||
a.actionType = Site.current().postActionTypeById(a.id);
|
||||
a.count = a.count || 0;
|
||||
const actionSummary = ActionSummary.create(a);
|
||||
lookup[a.actionType.name_key] = actionSummary;
|
||||
|
||||
if (a.actionType.name_key === "like") {
|
||||
json.likeAction = actionSummary;
|
||||
}
|
||||
return actionSummary;
|
||||
});
|
||||
|
||||
json.actionByName = lookup;
|
||||
}
|
||||
|
||||
if (json && json.reply_to_user) {
|
||||
json.reply_to_user = User.create(json.reply_to_user);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
static updateBookmark(postId, bookmarked) {
|
||||
return ajax(`/posts/${postId}/bookmark`, {
|
||||
type: "PUT",
|
||||
data: { bookmarked },
|
||||
});
|
||||
}
|
||||
|
||||
static destroyBookmark(postId) {
|
||||
return ajax(`/posts/${postId}/bookmark`, {
|
||||
type: "DELETE",
|
||||
});
|
||||
}
|
||||
|
||||
static deleteMany(post_ids, { agreeWithFirstReplyFlag = true } = {}) {
|
||||
return ajax("/posts/destroy_many", {
|
||||
type: "DELETE",
|
||||
data: { post_ids, agree_with_first_reply_flag: agreeWithFirstReplyFlag },
|
||||
});
|
||||
}
|
||||
|
||||
static mergePosts(post_ids) {
|
||||
return ajax("/posts/merge_posts", {
|
||||
type: "PUT",
|
||||
data: { post_ids },
|
||||
}).catch(popupAjaxError);
|
||||
}
|
||||
|
||||
static loadRevision(postId, version) {
|
||||
return ajax(`/posts/${postId}/revisions/${version}.json`).then((result) =>
|
||||
EmberObject.create(result)
|
||||
);
|
||||
}
|
||||
|
||||
static hideRevision(postId, version) {
|
||||
return ajax(`/posts/${postId}/revisions/${version}/hide`, {
|
||||
type: "PUT",
|
||||
});
|
||||
}
|
||||
|
||||
static permanentlyDeleteRevisions(postId) {
|
||||
return ajax(`/posts/${postId}/revisions/permanently_delete`, {
|
||||
type: "DELETE",
|
||||
});
|
||||
}
|
||||
|
||||
static showRevision(postId, version) {
|
||||
return ajax(`/posts/${postId}/revisions/${version}/show`, {
|
||||
type: "PUT",
|
||||
});
|
||||
}
|
||||
|
||||
static loadRawEmail(postId) {
|
||||
return ajax(`/posts/${postId}/raw-email.json`);
|
||||
}
|
||||
|
||||
customShare = null;
|
||||
|
||||
@equal("trust_level", 0) new_user;
|
||||
@equal("post_number", 1) firstPost;
|
||||
@or("deleted_at", "deletedViaTopic") deleted;
|
||||
@not("deleted") notDeleted;
|
||||
@propertyEqual("topic.details.created_by.id", "user_id") topicOwner;
|
||||
|
||||
// Posts can show up as deleted if the topic is deleted
|
||||
@and("firstPost", "topic.deleted_at") deletedViaTopic;
|
||||
|
||||
@discourseComputed("url", "customShare")
|
||||
shareUrl(url) {
|
||||
|
@ -29,30 +120,22 @@ const Post = RestModel.extend({
|
|||
|
||||
const user = User.current();
|
||||
return resolveShareUrl(url, user);
|
||||
},
|
||||
|
||||
new_user: equal("trust_level", 0),
|
||||
firstPost: equal("post_number", 1),
|
||||
|
||||
// Posts can show up as deleted if the topic is deleted
|
||||
deletedViaTopic: and("firstPost", "topic.deleted_at"),
|
||||
deleted: or("deleted_at", "deletedViaTopic"),
|
||||
notDeleted: not("deleted"),
|
||||
}
|
||||
|
||||
@discourseComputed("name", "username")
|
||||
showName(name, username) {
|
||||
return name && name !== username && this.siteSettings.display_name_on_posts;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("firstPost", "deleted_by", "topic.deleted_by")
|
||||
postDeletedBy(firstPost, deletedBy, topicDeletedBy) {
|
||||
return firstPost ? topicDeletedBy : deletedBy;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("firstPost", "deleted_at", "topic.deleted_at")
|
||||
postDeletedAt(firstPost, deletedAt, topicDeletedAt) {
|
||||
return firstPost ? topicDeletedAt : deletedAt;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("post_number", "topic_id", "topic.slug")
|
||||
url(post_number, topic_id, topicSlug) {
|
||||
|
@ -61,18 +144,18 @@ const Post = RestModel.extend({
|
|||
topic_id || this.get("topic.id"),
|
||||
post_number
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
// Don't drop the /1
|
||||
@discourseComputed("post_number", "url")
|
||||
urlWithNumber(postNumber, baseUrl) {
|
||||
return postNumber === 1 ? `${baseUrl}/1` : baseUrl;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("username")
|
||||
usernameUrl: userPath,
|
||||
|
||||
topicOwner: propertyEqual("topic.details.created_by.id", "user_id"),
|
||||
usernameUrl(username) {
|
||||
return userPath(username);
|
||||
}
|
||||
|
||||
updatePostField(field, value) {
|
||||
const data = {};
|
||||
|
@ -81,7 +164,7 @@ const Post = RestModel.extend({
|
|||
return ajax(`/posts/${this.id}/${field}`, { type: "PUT", data })
|
||||
.then(() => this.set(field, value))
|
||||
.catch(popupAjaxError);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("link_counts.@each.internal")
|
||||
internalLinks() {
|
||||
|
@ -90,7 +173,7 @@ const Post = RestModel.extend({
|
|||
}
|
||||
|
||||
return this.link_counts.filterBy("internal").filterBy("title");
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("actions_summary.@each.can_act")
|
||||
flagsAvailable() {
|
||||
|
@ -103,7 +186,7 @@ const Post = RestModel.extend({
|
|||
return this.site.flagTypes.filter((item) =>
|
||||
this.get(`actionByName.${item.name_key}.can_act`)
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed(
|
||||
"siteSettings.use_pg_headlines_for_excerpt",
|
||||
|
@ -111,25 +194,25 @@ const Post = RestModel.extend({
|
|||
)
|
||||
useTopicTitleHeadline(enabled, title) {
|
||||
return enabled && title;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("topic_title_headline")
|
||||
topicTitleHeadline(title) {
|
||||
return fancyTitle(title, this.siteSettings.support_mixed_text_direction);
|
||||
},
|
||||
}
|
||||
|
||||
afterUpdate(res) {
|
||||
if (res.category) {
|
||||
this.site.updateCategory(res.category);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
updateProperties() {
|
||||
return {
|
||||
post: { raw: this.raw, edit_reason: this.editReason },
|
||||
image_sizes: this.imageSizes,
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
createProperties() {
|
||||
// composer only used once, defer the dependency
|
||||
|
@ -148,7 +231,7 @@ const Post = RestModel.extend({
|
|||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
}
|
||||
|
||||
// Expands the first post's content, if embedded and shortened.
|
||||
expand() {
|
||||
|
@ -158,7 +241,7 @@ const Post = RestModel.extend({
|
|||
`<section class="expanded-embed">${post.cooked}</section>`
|
||||
);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
// Recover a deleted post
|
||||
recover() {
|
||||
|
@ -192,7 +275,7 @@ const Post = RestModel.extend({
|
|||
popupAjaxError(error);
|
||||
this.setProperties(initProperties);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
Changes the state of the post to be deleted. Does not call the server, that should be
|
||||
|
@ -231,7 +314,7 @@ const Post = RestModel.extend({
|
|||
}
|
||||
|
||||
return promise || Promise.resolve();
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
Changes the state of the post to NOT be deleted. Does not call the server.
|
||||
|
@ -250,7 +333,7 @@ const Post = RestModel.extend({
|
|||
user_deleted: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
destroy(deletedBy, opts) {
|
||||
return this.setDeletedState(deletedBy).then(() => {
|
||||
|
@ -259,7 +342,7 @@ const Post = RestModel.extend({
|
|||
type: "DELETE",
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
Updates a post from another's attributes. This will normally happen when a post is loading but
|
||||
|
@ -291,23 +374,23 @@ const Post = RestModel.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
expandHidden() {
|
||||
return ajax(`/posts/${this.id}/cooked.json`).then((result) => {
|
||||
this.setProperties({ cooked: result.cooked, cooked_hidden: false });
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
rebake() {
|
||||
return ajax(`/posts/${this.id}/rebake`, { type: "PUT" }).catch(
|
||||
popupAjaxError
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
unhide() {
|
||||
return ajax(`/posts/${this.id}/unhide`, { type: "PUT" });
|
||||
},
|
||||
}
|
||||
|
||||
createBookmark(data) {
|
||||
this.setProperties({
|
||||
|
@ -324,12 +407,12 @@ const Post = RestModel.extend({
|
|||
targetId: this.id,
|
||||
});
|
||||
this.appEvents.trigger("post-stream:refresh", { id: this.id });
|
||||
},
|
||||
}
|
||||
|
||||
deleteBookmark(bookmarked) {
|
||||
this.set("topic.bookmarked", bookmarked);
|
||||
this.clearBookmark();
|
||||
},
|
||||
}
|
||||
|
||||
clearBookmark() {
|
||||
this.setProperties({
|
||||
|
@ -344,14 +427,14 @@ const Post = RestModel.extend({
|
|||
target: "post",
|
||||
targetId: this.id,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
updateActionsSummary(json) {
|
||||
if (json && json.id === this.id) {
|
||||
json = Post.munge(json);
|
||||
this.set("actions_summary", json.actions_summary);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
updateLikeCount(count, userId, eventType) {
|
||||
let ownAction = User.current()?.id === userId;
|
||||
|
@ -385,101 +468,15 @@ const Post = RestModel.extend({
|
|||
Object.assign(this.actionByName["like"], newActionObject);
|
||||
Object.assign(this.likeAction, newActionObject);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
revertToRevision(version) {
|
||||
return ajax(`/posts/${this.id}/revisions/${version}/revert`, {
|
||||
type: "PUT",
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
get topicNotificationLevel() {
|
||||
return this.topic.details.notification_level;
|
||||
},
|
||||
});
|
||||
|
||||
Post.reopenClass({
|
||||
munge(json) {
|
||||
if (json.actions_summary) {
|
||||
const lookup = EmberObject.create();
|
||||
|
||||
// this area should be optimized, it is creating way too many objects per post
|
||||
json.actions_summary = json.actions_summary.map((a) => {
|
||||
a.actionType = Site.current().postActionTypeById(a.id);
|
||||
a.count = a.count || 0;
|
||||
const actionSummary = ActionSummary.create(a);
|
||||
lookup[a.actionType.name_key] = actionSummary;
|
||||
|
||||
if (a.actionType.name_key === "like") {
|
||||
json.likeAction = actionSummary;
|
||||
}
|
||||
return actionSummary;
|
||||
});
|
||||
|
||||
json.actionByName = lookup;
|
||||
}
|
||||
|
||||
if (json && json.reply_to_user) {
|
||||
json.reply_to_user = User.create(json.reply_to_user);
|
||||
}
|
||||
|
||||
return json;
|
||||
},
|
||||
|
||||
updateBookmark(postId, bookmarked) {
|
||||
return ajax(`/posts/${postId}/bookmark`, {
|
||||
type: "PUT",
|
||||
data: { bookmarked },
|
||||
});
|
||||
},
|
||||
|
||||
destroyBookmark(postId) {
|
||||
return ajax(`/posts/${postId}/bookmark`, {
|
||||
type: "DELETE",
|
||||
});
|
||||
},
|
||||
|
||||
deleteMany(post_ids, { agreeWithFirstReplyFlag = true } = {}) {
|
||||
return ajax("/posts/destroy_many", {
|
||||
type: "DELETE",
|
||||
data: { post_ids, agree_with_first_reply_flag: agreeWithFirstReplyFlag },
|
||||
});
|
||||
},
|
||||
|
||||
mergePosts(post_ids) {
|
||||
return ajax("/posts/merge_posts", {
|
||||
type: "PUT",
|
||||
data: { post_ids },
|
||||
}).catch(popupAjaxError);
|
||||
},
|
||||
|
||||
loadRevision(postId, version) {
|
||||
return ajax(`/posts/${postId}/revisions/${version}.json`).then((result) =>
|
||||
EmberObject.create(result)
|
||||
);
|
||||
},
|
||||
|
||||
hideRevision(postId, version) {
|
||||
return ajax(`/posts/${postId}/revisions/${version}/hide`, {
|
||||
type: "PUT",
|
||||
});
|
||||
},
|
||||
|
||||
permanentlyDeleteRevisions(postId) {
|
||||
return ajax(`/posts/${postId}/revisions/permanently_delete`, {
|
||||
type: "DELETE",
|
||||
});
|
||||
},
|
||||
|
||||
showRevision(postId, version) {
|
||||
return ajax(`/posts/${postId}/revisions/${version}/show`, {
|
||||
type: "PUT",
|
||||
});
|
||||
},
|
||||
|
||||
loadRawEmail(postId) {
|
||||
return ajax(`/posts/${postId}/raw-email.json`);
|
||||
},
|
||||
});
|
||||
|
||||
export default Post;
|
||||
|
|
|
@ -45,20 +45,277 @@ export function loadTopicView(topic, args) {
|
|||
export const ID_CONSTRAINT = /^\d+$/;
|
||||
let _customLastUnreadUrlCallbacks = [];
|
||||
|
||||
const Topic = RestModel.extend({
|
||||
message: null,
|
||||
errorLoading: false,
|
||||
export default class Topic extends RestModel {
|
||||
static NotificationLevel = {
|
||||
WATCHING: 3,
|
||||
TRACKING: 2,
|
||||
REGULAR: 1,
|
||||
MUTED: 0,
|
||||
};
|
||||
|
||||
static munge(json) {
|
||||
// ensure we are not overriding category computed property
|
||||
delete json.category;
|
||||
json.bookmarks = json.bookmarks || [];
|
||||
return json;
|
||||
}
|
||||
|
||||
static createActionSummary(result) {
|
||||
if (result.actions_summary) {
|
||||
const lookup = EmberObject.create();
|
||||
result.actions_summary = result.actions_summary.map((a) => {
|
||||
a.post = result;
|
||||
a.actionType = Site.current().postActionTypeById(a.id);
|
||||
const actionSummary = ActionSummary.create(a);
|
||||
lookup.set(a.actionType.get("name_key"), actionSummary);
|
||||
return actionSummary;
|
||||
});
|
||||
result.set("actionByName", lookup);
|
||||
}
|
||||
}
|
||||
|
||||
static update(topic, props, opts = {}) {
|
||||
// We support `category_id` and `categoryId` for compatibility
|
||||
if (typeof props.categoryId !== "undefined") {
|
||||
props.category_id = props.categoryId;
|
||||
delete props.categoryId;
|
||||
}
|
||||
|
||||
// Make sure we never change the category for private messages
|
||||
if (topic.get("isPrivateMessage")) {
|
||||
delete props.category_id;
|
||||
}
|
||||
|
||||
const data = { ...props };
|
||||
if (opts.fastEdit) {
|
||||
data.keep_existing_draft = true;
|
||||
}
|
||||
return ajax(topic.get("url"), {
|
||||
type: "PUT",
|
||||
data: JSON.stringify(data),
|
||||
contentType: "application/json",
|
||||
}).then((result) => {
|
||||
// The title can be cleaned up server side
|
||||
props.title = result.basic_topic.title;
|
||||
props.fancy_title = result.basic_topic.fancy_title;
|
||||
if (topic.is_shared_draft) {
|
||||
props.destination_category_id = props.category_id;
|
||||
delete props.category_id;
|
||||
}
|
||||
topic.setProperties(props);
|
||||
});
|
||||
}
|
||||
|
||||
static create() {
|
||||
const result = super.create.apply(this, arguments);
|
||||
this.createActionSummary(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Load a topic, but accepts a set of filters
|
||||
static find(topicId, opts) {
|
||||
let url = getURL("/t/") + topicId;
|
||||
if (opts.nearPost) {
|
||||
url += `/${opts.nearPost}`;
|
||||
}
|
||||
|
||||
const data = {};
|
||||
if (opts.postsAfter) {
|
||||
data.posts_after = opts.postsAfter;
|
||||
}
|
||||
if (opts.postsBefore) {
|
||||
data.posts_before = opts.postsBefore;
|
||||
}
|
||||
if (opts.trackVisit) {
|
||||
data.track_visit = true;
|
||||
}
|
||||
|
||||
// Add username filters if we have them
|
||||
if (opts.userFilters && opts.userFilters.length > 0) {
|
||||
data.username_filters = [];
|
||||
opts.userFilters.forEach(function (username) {
|
||||
data.username_filters.push(username);
|
||||
});
|
||||
}
|
||||
|
||||
// Add the summary of filter if we have it
|
||||
if (opts.summary === true) {
|
||||
data.summary = true;
|
||||
}
|
||||
|
||||
// Check the preload store. If not, load it via JSON
|
||||
return ajax(`${url}.json`, { data });
|
||||
}
|
||||
|
||||
static changeOwners(topicId, opts) {
|
||||
const promise = ajax(`/t/${topicId}/change-owner`, {
|
||||
type: "POST",
|
||||
data: opts,
|
||||
}).then((result) => {
|
||||
if (result.success) {
|
||||
return result;
|
||||
}
|
||||
promise.reject(new Error("error changing ownership of posts"));
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
static changeTimestamp(topicId, timestamp) {
|
||||
const promise = ajax(`/t/${topicId}/change-timestamp`, {
|
||||
type: "PUT",
|
||||
data: { timestamp },
|
||||
}).then((result) => {
|
||||
if (result.success) {
|
||||
return result;
|
||||
}
|
||||
promise.reject(new Error("error updating timestamp of topic"));
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
static bulkOperation(topics, operation, options, tracked) {
|
||||
const data = {
|
||||
topic_ids: topics.mapBy("id"),
|
||||
operation,
|
||||
tracked,
|
||||
};
|
||||
|
||||
if (options) {
|
||||
if (options.select) {
|
||||
data.silent = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ajax("/topics/bulk", {
|
||||
type: "PUT",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
static bulkOperationByFilter(filter, operation, options, tracked) {
|
||||
const data = { filter, operation, tracked };
|
||||
|
||||
if (options) {
|
||||
if (options.categoryId) {
|
||||
data.category_id = options.categoryId;
|
||||
}
|
||||
if (options.includeSubcategories) {
|
||||
data.include_subcategories = true;
|
||||
}
|
||||
if (options.tagName) {
|
||||
data.tag_name = options.tagName;
|
||||
}
|
||||
|
||||
if (options.private_message_inbox) {
|
||||
data.private_message_inbox = options.private_message_inbox;
|
||||
|
||||
if (options.group_name) {
|
||||
data.group_name = options.group_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ajax("/topics/bulk", {
|
||||
type: "PUT",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
static resetNew(category, include_subcategories, opts = {}) {
|
||||
let { tracked, tag, topicIds } = {
|
||||
tracked: false,
|
||||
tag: null,
|
||||
topicIds: null,
|
||||
...opts,
|
||||
};
|
||||
|
||||
const data = { tracked };
|
||||
if (category) {
|
||||
data.category_id = category.id;
|
||||
data.include_subcategories = include_subcategories;
|
||||
}
|
||||
if (tag) {
|
||||
data.tag_id = tag.id;
|
||||
}
|
||||
if (topicIds) {
|
||||
data.topic_ids = topicIds;
|
||||
}
|
||||
|
||||
if (opts.dismissPosts) {
|
||||
data.dismiss_posts = opts.dismissPosts;
|
||||
}
|
||||
|
||||
if (opts.dismissTopics) {
|
||||
data.dismiss_topics = opts.dismissTopics;
|
||||
}
|
||||
|
||||
if (opts.untrack) {
|
||||
data.untrack = opts.untrack;
|
||||
}
|
||||
|
||||
return ajax("/topics/reset-new", { type: "PUT", data });
|
||||
}
|
||||
|
||||
static pmResetNew(opts = {}) {
|
||||
const data = {};
|
||||
|
||||
if (opts.topicIds) {
|
||||
data.topic_ids = opts.topicIds;
|
||||
}
|
||||
|
||||
if (opts.inbox) {
|
||||
data.inbox = opts.inbox;
|
||||
|
||||
if (opts.groupName) {
|
||||
data.group_name = opts.groupName;
|
||||
}
|
||||
}
|
||||
|
||||
return ajax("/topics/pm-reset-new", { type: "PUT", data });
|
||||
}
|
||||
|
||||
static idForSlug(slug) {
|
||||
return ajax(`/t/id_for/${slug}`);
|
||||
}
|
||||
|
||||
static setSlowMode(topicId, seconds, enabledUntil) {
|
||||
const data = { seconds };
|
||||
data.enabled_until = enabledUntil;
|
||||
|
||||
return ajax(`/t/${topicId}/slow_mode`, { type: "PUT", data });
|
||||
}
|
||||
|
||||
static async applyTransformations(topics) {
|
||||
await applyModelTransformations("topic", topics);
|
||||
}
|
||||
|
||||
message = null;
|
||||
errorLoading = false;
|
||||
|
||||
@alias("lastPoster.user") lastPosterUser;
|
||||
@alias("lastPoster.primary_group") lastPosterGroup;
|
||||
@alias("details.allowed_groups") allowedGroups;
|
||||
@notEmpty("deleted_at") deleted;
|
||||
@fmt("url", "%@/print") printUrl;
|
||||
@equal("archetype", "private_message") isPrivateMessage;
|
||||
@equal("archetype", "banner") isBanner;
|
||||
@alias("bookmarks.length") bookmarkCount;
|
||||
@and("pinned", "category.isUncategorizedCategory") isPinnedUncategorized;
|
||||
@notEmpty("excerpt") hasExcerpt;
|
||||
@propertyEqual("last_read_post_number", "highest_post_number") readLastPost;
|
||||
@and("pinned", "readLastPost") canClearPin;
|
||||
@or("details.can_edit", "details.can_edit_tags") canEditTags;
|
||||
|
||||
@discourseComputed("last_read_post_number", "highest_post_number")
|
||||
visited(lastReadPostNumber, highestPostNumber) {
|
||||
// >= to handle case where there are deleted posts at the end of the topic
|
||||
return lastReadPostNumber >= highestPostNumber;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("posters.firstObject")
|
||||
creator(poster) {
|
||||
return poster && poster.user;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("posters.[]")
|
||||
lastPoster(posters) {
|
||||
|
@ -66,11 +323,7 @@ const Topic = RestModel.extend({
|
|||
const latest = posters.filter((p) => p.extras?.includes("latest"))[0];
|
||||
return latest || posters.firstObject;
|
||||
}
|
||||
},
|
||||
|
||||
lastPosterUser: alias("lastPoster.user"),
|
||||
lastPosterGroup: alias("lastPoster.primary_group"),
|
||||
allowedGroups: alias("details.allowed_groups"),
|
||||
}
|
||||
|
||||
@discourseComputed("posters.[]", "participants.[]", "allowed_user_count")
|
||||
featuredUsers(posters, participants, allowedUserCount) {
|
||||
|
@ -109,12 +362,12 @@ const Topic = RestModel.extend({
|
|||
}
|
||||
|
||||
return users;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("fancy_title")
|
||||
fancyTitle(title) {
|
||||
return fancyTitle(title, this.siteSettings.support_mixed_text_direction);
|
||||
},
|
||||
}
|
||||
|
||||
// returns createdAt if there's no bumped date
|
||||
@discourseComputed("bumped_at", "createdAt")
|
||||
|
@ -124,7 +377,7 @@ const Topic = RestModel.extend({
|
|||
} else {
|
||||
return createdAt;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("bumpedAt", "createdAt")
|
||||
bumpedAtTitle(bumpedAt, createdAt) {
|
||||
|
@ -139,12 +392,12 @@ const Topic = RestModel.extend({
|
|||
})}\n${I18n.t("topic.bumped_at", { date: longDate(bumpedAt) })}`
|
||||
: I18n.t("topic.created_at", { date: longDate(createdAt) });
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("created_at")
|
||||
createdAt(created_at) {
|
||||
return new Date(created_at);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed
|
||||
postStream() {
|
||||
|
@ -152,7 +405,7 @@ const Topic = RestModel.extend({
|
|||
id: this.id,
|
||||
topic: this,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("tags")
|
||||
visibleListTags(tags) {
|
||||
|
@ -170,66 +423,62 @@ const Topic = RestModel.extend({
|
|||
});
|
||||
|
||||
return newTags;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("related_messages")
|
||||
relatedMessages(relatedMessages) {
|
||||
if (relatedMessages) {
|
||||
return relatedMessages.map((st) => this.store.createRecord("topic", st));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("suggested_topics")
|
||||
suggestedTopics(suggestedTopics) {
|
||||
if (suggestedTopics) {
|
||||
return suggestedTopics.map((st) => this.store.createRecord("topic", st));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("posts_count")
|
||||
replyCount(postsCount) {
|
||||
return postsCount - 1;
|
||||
},
|
||||
}
|
||||
|
||||
get details() {
|
||||
return (this._details ??= this.store.createRecord("topicDetails", {
|
||||
id: this.id,
|
||||
topic: this,
|
||||
}));
|
||||
},
|
||||
}
|
||||
|
||||
set details(value) {
|
||||
this._details = value;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("visible")
|
||||
invisible(visible) {
|
||||
return visible !== undefined ? !visible : undefined;
|
||||
},
|
||||
|
||||
deleted: notEmpty("deleted_at"),
|
||||
}
|
||||
|
||||
@discourseComputed("id")
|
||||
searchContext(id) {
|
||||
return { type: "topic", id };
|
||||
},
|
||||
}
|
||||
|
||||
@computed("category_id")
|
||||
get category() {
|
||||
return Category.findById(this.category_id);
|
||||
},
|
||||
}
|
||||
|
||||
set category(newCategory) {
|
||||
this.set("category_id", newCategory?.id);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("url")
|
||||
shareUrl(url) {
|
||||
const user = User.current();
|
||||
return resolveShareUrl(url, user);
|
||||
},
|
||||
|
||||
printUrl: fmt("url", "%@/print"),
|
||||
}
|
||||
|
||||
@discourseComputed("id", "slug")
|
||||
url(id, slug) {
|
||||
|
@ -238,7 +487,7 @@ const Topic = RestModel.extend({
|
|||
slug = "topic";
|
||||
}
|
||||
return `${getURL("/t/")}${slug}/${id}`;
|
||||
},
|
||||
}
|
||||
|
||||
// Helper to build a Url with a post number
|
||||
urlForPostNumber(postNumber) {
|
||||
|
@ -247,7 +496,7 @@ const Topic = RestModel.extend({
|
|||
url += `/${postNumber}`;
|
||||
}
|
||||
return url;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("unread_posts", "new_posts")
|
||||
totalUnread(unreadPosts, newPosts) {
|
||||
|
@ -255,7 +504,7 @@ const Topic = RestModel.extend({
|
|||
id: "discourse.topic.totalUnread",
|
||||
});
|
||||
return unreadPosts || newPosts;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("unread_posts", "new_posts")
|
||||
displayNewPosts(unreadPosts, newPosts) {
|
||||
|
@ -264,12 +513,12 @@ const Topic = RestModel.extend({
|
|||
{ id: "discourse.topic.totalUnread" }
|
||||
);
|
||||
return unreadPosts || newPosts;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("last_read_post_number", "url")
|
||||
lastReadUrl(lastReadPostNumber) {
|
||||
return this.urlForPostNumber(lastReadPostNumber);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("last_read_post_number", "highest_post_number", "url")
|
||||
lastUnreadUrl(lastReadPostNumber, highestPostNumber) {
|
||||
|
@ -299,28 +548,28 @@ const Topic = RestModel.extend({
|
|||
}
|
||||
|
||||
return this.urlForPostNumber(postNumber);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("highest_post_number", "url")
|
||||
lastPostUrl(highestPostNumber) {
|
||||
return this.urlForPostNumber(highestPostNumber);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("url")
|
||||
firstPostUrl() {
|
||||
return this.urlForPostNumber(1);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("url")
|
||||
summaryUrl() {
|
||||
const summaryQueryString = this.has_summary ? "?filter=summary" : "";
|
||||
return `${this.urlForPostNumber(1)}${summaryQueryString}`;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("last_poster.username")
|
||||
lastPosterUrl(username) {
|
||||
return userPath(username);
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("views")
|
||||
viewsHeat(v) {
|
||||
|
@ -334,20 +583,17 @@ const Topic = RestModel.extend({
|
|||
return "heatmap-low";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("archetype")
|
||||
archetypeObject(archetype) {
|
||||
return Site.currentProp("archetypes").findBy("id", archetype);
|
||||
},
|
||||
|
||||
isPrivateMessage: equal("archetype", "private_message"),
|
||||
isBanner: equal("archetype", "banner"),
|
||||
}
|
||||
|
||||
toggleStatus(property) {
|
||||
this.toggleProperty(property);
|
||||
return this.saveStatus(property, !!this.get(property));
|
||||
},
|
||||
}
|
||||
|
||||
saveStatus(property, value, until) {
|
||||
if (property === "closed") {
|
||||
|
@ -361,23 +607,23 @@ const Topic = RestModel.extend({
|
|||
until,
|
||||
},
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
makeBanner() {
|
||||
return ajax(`/t/${this.id}/make-banner`, { type: "PUT" }).then(() =>
|
||||
this.set("archetype", "banner")
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
removeBanner() {
|
||||
return ajax(`/t/${this.id}/remove-banner`, {
|
||||
type: "PUT",
|
||||
}).then(() => this.set("archetype", "regular"));
|
||||
},
|
||||
}
|
||||
|
||||
afterPostBookmarked(post) {
|
||||
post.set("bookmarked", true);
|
||||
},
|
||||
}
|
||||
|
||||
firstPost() {
|
||||
const postStream = this.postStream;
|
||||
|
@ -393,7 +639,7 @@ const Topic = RestModel.extend({
|
|||
} else {
|
||||
return this.postStream.loadPostByPostNumber(1);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
postById(id) {
|
||||
const loaded = this.postStream.findLoadedPost(id);
|
||||
|
@ -402,13 +648,11 @@ const Topic = RestModel.extend({
|
|||
}
|
||||
|
||||
return this.postStream.loadPost(id);
|
||||
},
|
||||
}
|
||||
|
||||
deleteBookmarks() {
|
||||
return ajax(`/t/${this.id}/remove_bookmarks`, { type: "PUT" });
|
||||
},
|
||||
|
||||
bookmarkCount: alias("bookmarks.length"),
|
||||
}
|
||||
|
||||
removeBookmark(id) {
|
||||
if (!this.bookmarks) {
|
||||
|
@ -430,7 +674,7 @@ const Topic = RestModel.extend({
|
|||
);
|
||||
this.set("bookmarked", this.bookmarks.length);
|
||||
this.incrementProperty("bookmarksWereChanged");
|
||||
},
|
||||
}
|
||||
|
||||
clearBookmarks() {
|
||||
this.toggleProperty("bookmarked");
|
||||
|
@ -447,28 +691,28 @@ const Topic = RestModel.extend({
|
|||
this.set("bookmarks", []);
|
||||
|
||||
return postIds;
|
||||
},
|
||||
}
|
||||
|
||||
createGroupInvite(group) {
|
||||
return ajax(`/t/${this.id}/invite-group`, {
|
||||
type: "POST",
|
||||
data: { group },
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
createInvite(user, group_ids, custom_message) {
|
||||
return ajax(`/t/${this.id}/invite`, {
|
||||
type: "POST",
|
||||
data: { user, group_ids, custom_message },
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
generateInviteLink(email, group_ids, topic_id) {
|
||||
return ajax("/invites", {
|
||||
type: "POST",
|
||||
data: { email, skip_email: true, group_ids, topic_id },
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
// Delete this topic
|
||||
destroy(deleted_by, opts = {}) {
|
||||
|
@ -502,7 +746,7 @@ const Topic = RestModel.extend({
|
|||
}
|
||||
})
|
||||
.catch(popupAjaxError);
|
||||
},
|
||||
}
|
||||
|
||||
// Recover this topic if deleted
|
||||
recover() {
|
||||
|
@ -516,7 +760,7 @@ const Topic = RestModel.extend({
|
|||
data: { context: window.location.pathname },
|
||||
type: "PUT",
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
// Update our attributes from a JSON result
|
||||
updateFromJson(json) {
|
||||
|
@ -543,15 +787,13 @@ const Topic = RestModel.extend({
|
|||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
}
|
||||
|
||||
reload() {
|
||||
return ajax(`/t/${this.id}`, { type: "GET" }).then((topic_json) =>
|
||||
this.updateFromJson(topic_json)
|
||||
);
|
||||
},
|
||||
|
||||
isPinnedUncategorized: and("pinned", "category.isUncategorizedCategory"),
|
||||
}
|
||||
|
||||
clearPin() {
|
||||
// Clear the pin optimistically from the object
|
||||
|
@ -563,7 +805,7 @@ const Topic = RestModel.extend({
|
|||
// On error, put the pin back
|
||||
this.setProperties({ pinned: true, unpinned: false });
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
togglePinnedForUser() {
|
||||
if (this.pinned) {
|
||||
|
@ -571,7 +813,7 @@ const Topic = RestModel.extend({
|
|||
} else {
|
||||
this.rePin();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
rePin() {
|
||||
// Clear the pin optimistically from the object
|
||||
|
@ -583,23 +825,17 @@ const Topic = RestModel.extend({
|
|||
// On error, put the pin back
|
||||
this.setProperties({ pinned: true, unpinned: false });
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
@discourseComputed("excerpt")
|
||||
escapedExcerpt(excerpt) {
|
||||
return emojiUnescape(excerpt);
|
||||
},
|
||||
|
||||
hasExcerpt: notEmpty("excerpt"),
|
||||
}
|
||||
|
||||
@discourseComputed("excerpt")
|
||||
excerptTruncated(excerpt) {
|
||||
return excerpt && excerpt.slice(-8) === "…";
|
||||
},
|
||||
|
||||
readLastPost: propertyEqual("last_read_post_number", "highest_post_number"),
|
||||
canClearPin: and("pinned", "readLastPost"),
|
||||
canEditTags: or("details.can_edit", "details.can_edit_tags"),
|
||||
}
|
||||
|
||||
archiveMessage() {
|
||||
this.set("archiving", true);
|
||||
|
@ -617,7 +853,7 @@ const Topic = RestModel.extend({
|
|||
.finally(() => this.set("archiving", false));
|
||||
|
||||
return promise;
|
||||
},
|
||||
}
|
||||
|
||||
moveToInbox() {
|
||||
this.set("archiving", true);
|
||||
|
@ -633,7 +869,7 @@ const Topic = RestModel.extend({
|
|||
.finally(() => this.set("archiving", false));
|
||||
|
||||
return promise;
|
||||
},
|
||||
}
|
||||
|
||||
publish() {
|
||||
return ajax(`/t/${this.id}/publish`, {
|
||||
|
@ -642,7 +878,7 @@ const Topic = RestModel.extend({
|
|||
})
|
||||
.then(() => this.set("destination_category_id", null))
|
||||
.catch(popupAjaxError);
|
||||
},
|
||||
}
|
||||
|
||||
updateDestinationCategory(categoryId) {
|
||||
this.set("destination_category_id", categoryId);
|
||||
|
@ -650,7 +886,7 @@ const Topic = RestModel.extend({
|
|||
type: "PUT",
|
||||
data: { category_id: categoryId },
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
convertTopic(type, opts) {
|
||||
let args = { type: "PUT" };
|
||||
|
@ -658,13 +894,13 @@ const Topic = RestModel.extend({
|
|||
args.data = { category_id: opts.categoryId };
|
||||
}
|
||||
return ajax(`/t/${this.id}/convert-topic/${type}`, args);
|
||||
},
|
||||
}
|
||||
|
||||
resetBumpDate() {
|
||||
return ajax(`/t/${this.id}/reset-bump-date`, { type: "PUT" }).catch(
|
||||
popupAjaxError
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
updateTags(tags) {
|
||||
if (!tags || tags.length === 0) {
|
||||
|
@ -675,254 +911,9 @@ const Topic = RestModel.extend({
|
|||
type: "PUT",
|
||||
data: { tags },
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Topic.reopenClass({
|
||||
NotificationLevel: {
|
||||
WATCHING: 3,
|
||||
TRACKING: 2,
|
||||
REGULAR: 1,
|
||||
MUTED: 0,
|
||||
},
|
||||
|
||||
munge(json) {
|
||||
// ensure we are not overriding category computed property
|
||||
delete json.category;
|
||||
json.bookmarks = json.bookmarks || [];
|
||||
return json;
|
||||
},
|
||||
|
||||
createActionSummary(result) {
|
||||
if (result.actions_summary) {
|
||||
const lookup = EmberObject.create();
|
||||
result.actions_summary = result.actions_summary.map((a) => {
|
||||
a.post = result;
|
||||
a.actionType = Site.current().postActionTypeById(a.id);
|
||||
const actionSummary = ActionSummary.create(a);
|
||||
lookup.set(a.actionType.get("name_key"), actionSummary);
|
||||
return actionSummary;
|
||||
});
|
||||
result.set("actionByName", lookup);
|
||||
}
|
||||
},
|
||||
|
||||
update(topic, props, opts = {}) {
|
||||
// We support `category_id` and `categoryId` for compatibility
|
||||
if (typeof props.categoryId !== "undefined") {
|
||||
props.category_id = props.categoryId;
|
||||
delete props.categoryId;
|
||||
}
|
||||
|
||||
// Make sure we never change the category for private messages
|
||||
if (topic.get("isPrivateMessage")) {
|
||||
delete props.category_id;
|
||||
}
|
||||
|
||||
const data = { ...props };
|
||||
if (opts.fastEdit) {
|
||||
data.keep_existing_draft = true;
|
||||
}
|
||||
return ajax(topic.get("url"), {
|
||||
type: "PUT",
|
||||
data: JSON.stringify(data),
|
||||
contentType: "application/json",
|
||||
}).then((result) => {
|
||||
// The title can be cleaned up server side
|
||||
props.title = result.basic_topic.title;
|
||||
props.fancy_title = result.basic_topic.fancy_title;
|
||||
if (topic.is_shared_draft) {
|
||||
props.destination_category_id = props.category_id;
|
||||
delete props.category_id;
|
||||
}
|
||||
topic.setProperties(props);
|
||||
});
|
||||
},
|
||||
|
||||
create() {
|
||||
const result = this._super.apply(this, arguments);
|
||||
this.createActionSummary(result);
|
||||
return result;
|
||||
},
|
||||
|
||||
// Load a topic, but accepts a set of filters
|
||||
find(topicId, opts) {
|
||||
let url = getURL("/t/") + topicId;
|
||||
if (opts.nearPost) {
|
||||
url += `/${opts.nearPost}`;
|
||||
}
|
||||
|
||||
const data = {};
|
||||
if (opts.postsAfter) {
|
||||
data.posts_after = opts.postsAfter;
|
||||
}
|
||||
if (opts.postsBefore) {
|
||||
data.posts_before = opts.postsBefore;
|
||||
}
|
||||
if (opts.trackVisit) {
|
||||
data.track_visit = true;
|
||||
}
|
||||
|
||||
// Add username filters if we have them
|
||||
if (opts.userFilters && opts.userFilters.length > 0) {
|
||||
data.username_filters = [];
|
||||
opts.userFilters.forEach(function (username) {
|
||||
data.username_filters.push(username);
|
||||
});
|
||||
}
|
||||
|
||||
// Add the summary of filter if we have it
|
||||
if (opts.summary === true) {
|
||||
data.summary = true;
|
||||
}
|
||||
|
||||
// Check the preload store. If not, load it via JSON
|
||||
return ajax(`${url}.json`, { data });
|
||||
},
|
||||
|
||||
changeOwners(topicId, opts) {
|
||||
const promise = ajax(`/t/${topicId}/change-owner`, {
|
||||
type: "POST",
|
||||
data: opts,
|
||||
}).then((result) => {
|
||||
if (result.success) {
|
||||
return result;
|
||||
}
|
||||
promise.reject(new Error("error changing ownership of posts"));
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
|
||||
changeTimestamp(topicId, timestamp) {
|
||||
const promise = ajax(`/t/${topicId}/change-timestamp`, {
|
||||
type: "PUT",
|
||||
data: { timestamp },
|
||||
}).then((result) => {
|
||||
if (result.success) {
|
||||
return result;
|
||||
}
|
||||
promise.reject(new Error("error updating timestamp of topic"));
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
|
||||
bulkOperation(topics, operation, options, tracked) {
|
||||
const data = {
|
||||
topic_ids: topics.mapBy("id"),
|
||||
operation,
|
||||
tracked,
|
||||
};
|
||||
|
||||
if (options) {
|
||||
if (options.select) {
|
||||
data.silent = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ajax("/topics/bulk", {
|
||||
type: "PUT",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
bulkOperationByFilter(filter, operation, options, tracked) {
|
||||
const data = { filter, operation, tracked };
|
||||
|
||||
if (options) {
|
||||
if (options.categoryId) {
|
||||
data.category_id = options.categoryId;
|
||||
}
|
||||
if (options.includeSubcategories) {
|
||||
data.include_subcategories = true;
|
||||
}
|
||||
if (options.tagName) {
|
||||
data.tag_name = options.tagName;
|
||||
}
|
||||
|
||||
if (options.private_message_inbox) {
|
||||
data.private_message_inbox = options.private_message_inbox;
|
||||
|
||||
if (options.group_name) {
|
||||
data.group_name = options.group_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ajax("/topics/bulk", {
|
||||
type: "PUT",
|
||||
data,
|
||||
});
|
||||
},
|
||||
|
||||
resetNew(category, include_subcategories, opts = {}) {
|
||||
let { tracked, tag, topicIds } = {
|
||||
tracked: false,
|
||||
tag: null,
|
||||
topicIds: null,
|
||||
...opts,
|
||||
};
|
||||
|
||||
const data = { tracked };
|
||||
if (category) {
|
||||
data.category_id = category.id;
|
||||
data.include_subcategories = include_subcategories;
|
||||
}
|
||||
if (tag) {
|
||||
data.tag_id = tag.id;
|
||||
}
|
||||
if (topicIds) {
|
||||
data.topic_ids = topicIds;
|
||||
}
|
||||
|
||||
if (opts.dismissPosts) {
|
||||
data.dismiss_posts = opts.dismissPosts;
|
||||
}
|
||||
|
||||
if (opts.dismissTopics) {
|
||||
data.dismiss_topics = opts.dismissTopics;
|
||||
}
|
||||
|
||||
if (opts.untrack) {
|
||||
data.untrack = opts.untrack;
|
||||
}
|
||||
|
||||
return ajax("/topics/reset-new", { type: "PUT", data });
|
||||
},
|
||||
|
||||
pmResetNew(opts = {}) {
|
||||
const data = {};
|
||||
|
||||
if (opts.topicIds) {
|
||||
data.topic_ids = opts.topicIds;
|
||||
}
|
||||
|
||||
if (opts.inbox) {
|
||||
data.inbox = opts.inbox;
|
||||
|
||||
if (opts.groupName) {
|
||||
data.group_name = opts.groupName;
|
||||
}
|
||||
}
|
||||
|
||||
return ajax("/topics/pm-reset-new", { type: "PUT", data });
|
||||
},
|
||||
|
||||
idForSlug(slug) {
|
||||
return ajax(`/t/id_for/${slug}`);
|
||||
},
|
||||
|
||||
setSlowMode(topicId, seconds, enabledUntil) {
|
||||
const data = { seconds };
|
||||
data.enabled_until = enabledUntil;
|
||||
|
||||
return ajax(`/t/${topicId}/slow_mode`, { type: "PUT", data });
|
||||
},
|
||||
|
||||
async applyTransformations(topics) {
|
||||
await applyModelTransformations("topic", topics);
|
||||
},
|
||||
});
|
||||
|
||||
function moveResult(result) {
|
||||
if (result.success) {
|
||||
// We should be hesitant to flush the map but moving ids is one rare case
|
||||
|
@ -952,5 +943,3 @@ export function registerCustomLastUnreadUrlCallback(fn) {
|
|||
export function clearCustomLastUnreadUrlCallbacks() {
|
||||
_customLastUnreadUrlCallbacks.clear();
|
||||
}
|
||||
|
||||
export default Topic;
|
||||
|
|
Loading…
Reference in New Issue
Block a user