mirror of
https://github.com/discourse/discourse.git
synced 2025-02-04 11:57:13 +08:00
f661fa609e
http://meta.discourse.org/t/is-it-better-for-discourse-to-use-javascript-or-coffeescript/3153
368 lines
12 KiB
JavaScript
368 lines
12 KiB
JavaScript
(function() {
|
|
|
|
window.Discourse.Post = Ember.Object.extend(Discourse.Presence, {
|
|
/* Url to this post
|
|
*/
|
|
|
|
url: (function() {
|
|
return Discourse.Utilities.postUrl(this.get('topic.slug') || this.get('topic_slug'), this.get('topic_id'), this.get('post_number'));
|
|
}).property('post_number', 'topic_id', 'topic.slug'),
|
|
originalPostUrl: (function() {
|
|
return "/t/" + (this.get('topic_id')) + "/" + (this.get('reply_to_post_number'));
|
|
}).property('reply_to_post_number'),
|
|
showUserReplyTab: (function() {
|
|
return this.get('reply_to_user') && (this.get('reply_to_post_number') < (this.get('post_number') - 1));
|
|
}).property('reply_to_user', 'reply_to_post_number', 'post_number'),
|
|
firstPost: (function() {
|
|
if (this.get('bestOfFirst') === true) {
|
|
return true;
|
|
}
|
|
return this.get('post_number') === 1;
|
|
}).property('post_number'),
|
|
hasHistory: (function() {
|
|
return this.get('version') > 1;
|
|
}).property('version'),
|
|
postElementId: (function() {
|
|
return "post_" + (this.get('post_number'));
|
|
}).property(),
|
|
/*
|
|
The class for the read icon of the post. It starts with read-icon then adds 'seen' or
|
|
'last-read' if the post has been seen or is the highest post number seen so far respectively.
|
|
*/
|
|
|
|
bookmarkClass: (function() {
|
|
var result, topic;
|
|
result = 'read-icon';
|
|
if (this.get('bookmarked')) {
|
|
return result + ' bookmarked';
|
|
}
|
|
topic = this.get('topic');
|
|
if (topic && topic.get('last_read_post_number') === this.get('post_number')) {
|
|
result += ' last-read';
|
|
} else {
|
|
if (this.get('read')) {
|
|
result += ' seen';
|
|
}
|
|
}
|
|
return result;
|
|
}).property('read', 'topic.last_read_post_number', 'bookmarked'),
|
|
/* Custom tooltips for the bookmark icons
|
|
*/
|
|
|
|
bookmarkTooltip: (function() {
|
|
var topic;
|
|
if (this.get('bookmarked')) {
|
|
return Em.String.i18n('bookmarks.created');
|
|
}
|
|
if (!this.get('read')) {
|
|
return "";
|
|
}
|
|
topic = this.get('topic');
|
|
if (topic && topic.get('last_read_post_number') === this.get('post_number')) {
|
|
return Em.String.i18n('bookmarks.last_read');
|
|
}
|
|
return Em.String.i18n('bookmarks.not_bookmarked');
|
|
}).property('read', 'topic.last_read_post_number', 'bookmarked'),
|
|
bookmarkedChanged: (function() {
|
|
var _this = this;
|
|
return jQuery.ajax({
|
|
url: "/posts/" + (this.get('id')) + "/bookmark",
|
|
type: 'PUT',
|
|
data: {
|
|
bookmarked: this.get('bookmarked') ? true : false
|
|
},
|
|
error: function(error) {
|
|
var errors;
|
|
errors = jQuery.parseJSON(error.responseText).errors;
|
|
bootbox.alert(errors[0]);
|
|
return _this.toggleProperty('bookmarked');
|
|
}
|
|
});
|
|
}).observes('bookmarked'),
|
|
internalLinks: (function() {
|
|
if (this.blank('link_counts')) {
|
|
return null;
|
|
}
|
|
return this.get('link_counts').filterProperty('internal').filterProperty('title');
|
|
}).property('link_counts.@each.internal'),
|
|
/* Edits are the version - 1, so version 2 = 1 edit
|
|
*/
|
|
|
|
editCount: (function() {
|
|
return this.get('version') - 1;
|
|
}).property('version'),
|
|
historyHeat: (function() {
|
|
var rightNow, updatedAt, updatedAtDate;
|
|
if (!(updatedAt = this.get('updated_at'))) {
|
|
return;
|
|
}
|
|
rightNow = new Date().getTime();
|
|
/* Show heat on age
|
|
*/
|
|
|
|
updatedAtDate = Date.create(updatedAt).getTime();
|
|
if (updatedAtDate > (rightNow - 60 * 60 * 1000 * 12)) {
|
|
return 'heatmap-high';
|
|
}
|
|
if (updatedAtDate > (rightNow - 60 * 60 * 1000 * 24)) {
|
|
return 'heatmap-med';
|
|
}
|
|
if (updatedAtDate > (rightNow - 60 * 60 * 1000 * 48)) {
|
|
return 'heatmap-low';
|
|
}
|
|
}).property('updated_at'),
|
|
flagsAvailable: (function() {
|
|
var _this = this;
|
|
return Discourse.get('site.flagTypes').filter(function(item) {
|
|
return _this.get("actionByName." + (item.get('name_key')) + ".can_act");
|
|
});
|
|
}).property('Discourse.site.flagTypes', 'actions_summary.@each.can_act'),
|
|
actionsHistory: (function() {
|
|
if (!this.present('actions_summary')) {
|
|
return null;
|
|
}
|
|
return this.get('actions_summary').filter(function(i) {
|
|
if (i.get('count') === 0) {
|
|
return false;
|
|
}
|
|
if (i.get('users') && i.get('users').length > 0) {
|
|
return true;
|
|
}
|
|
return !i.get('hidden');
|
|
});
|
|
}).property('actions_summary.@each.users', 'actions_summary.@each.count'),
|
|
/* Save a post and call the callback when done.
|
|
*/
|
|
|
|
save: function(complete, error) {
|
|
var data, metaData;
|
|
if (!this.get('newPost')) {
|
|
/* We're updating a post
|
|
*/
|
|
|
|
return jQuery.ajax({
|
|
url: "/posts/" + (this.get('id')),
|
|
type: 'PUT',
|
|
data: {
|
|
post: {
|
|
raw: this.get('raw')
|
|
},
|
|
image_sizes: this.get('imageSizes')
|
|
},
|
|
success: function(result) {
|
|
return typeof complete === "function" ? complete(Discourse.Post.create(result)) : void 0;
|
|
},
|
|
error: function(result) {
|
|
return typeof error === "function" ? error(result) : void 0;
|
|
}
|
|
});
|
|
} else {
|
|
/* We're saving a post
|
|
*/
|
|
|
|
data = {
|
|
post: this.getProperties('raw', 'topic_id', 'reply_to_post_number', 'category'),
|
|
archetype: this.get('archetype'),
|
|
title: this.get('title'),
|
|
image_sizes: this.get('imageSizes'),
|
|
target_usernames: this.get('target_usernames')
|
|
};
|
|
/* Put the metaData into the request
|
|
*/
|
|
|
|
if (metaData = this.get('metaData')) {
|
|
data.meta_data = {};
|
|
Ember.keys(metaData).forEach(function(key) {
|
|
data.meta_data[key] = metaData.get(key);
|
|
});
|
|
}
|
|
return jQuery.ajax({
|
|
type: 'POST',
|
|
url: "/posts",
|
|
data: data,
|
|
success: function(result) {
|
|
return typeof complete === "function" ? complete(Discourse.Post.create(result)) : void 0;
|
|
},
|
|
error: function(result) {
|
|
return typeof error === "function" ? error(result) : void 0;
|
|
}
|
|
});
|
|
}
|
|
},
|
|
recover: function() {
|
|
return jQuery.ajax("/posts/" + (this.get('id')) + "/recover", {
|
|
type: 'PUT',
|
|
cache: false
|
|
});
|
|
},
|
|
"delete": function(complete) {
|
|
return jQuery.ajax("/posts/" + (this.get('id')), {
|
|
type: 'DELETE',
|
|
success: function(result) {
|
|
return typeof complete === "function" ? complete() : void 0;
|
|
}
|
|
});
|
|
},
|
|
/*
|
|
Update the properties of this post from an obj, ignoring cooked as we should already
|
|
have that rendered.
|
|
*/
|
|
|
|
updateFromSave: function(obj) {
|
|
var lookup,
|
|
_this = this;
|
|
if (!obj) {
|
|
return;
|
|
}
|
|
Object.each(obj, function(key, val) {
|
|
if (key === 'actions_summary') {
|
|
return false;
|
|
}
|
|
if (val) {
|
|
return _this.set(key, val);
|
|
}
|
|
});
|
|
/* Rebuild actions summary
|
|
*/
|
|
|
|
this.set('actions_summary', Em.A());
|
|
if (obj.actions_summary) {
|
|
lookup = Em.Object.create();
|
|
obj.actions_summary.each(function(a) {
|
|
var actionSummary;
|
|
a.post = _this;
|
|
a.actionType = Discourse.get("site").postActionTypeById(a.id);
|
|
actionSummary = Discourse.ActionSummary.create(a);
|
|
_this.get('actions_summary').pushObject(actionSummary);
|
|
return lookup.set(a.actionType.get('name_key'), actionSummary);
|
|
});
|
|
return this.set('actionByName', lookup);
|
|
}
|
|
},
|
|
|
|
// Load replies to this post
|
|
loadReplies: function() {
|
|
var promise,
|
|
_this = this;
|
|
promise = new RSVP.Promise();
|
|
this.set('loadingReplies', true);
|
|
this.set('replies', []);
|
|
jQuery.getJSON("/posts/" + (this.get('id')) + "/replies", function(loaded) {
|
|
loaded.each(function(reply) {
|
|
var post;
|
|
post = Discourse.Post.create(reply);
|
|
post.set('topic', _this.get('topic'));
|
|
return _this.get('replies').pushObject(post);
|
|
});
|
|
_this.set('loadingReplies', false);
|
|
return promise.resolve();
|
|
});
|
|
return promise;
|
|
},
|
|
loadVersions: function(callback) {
|
|
return jQuery.get("/posts/" + (this.get('id')) + "/versions.json", function(result) {
|
|
return callback(result);
|
|
});
|
|
},
|
|
|
|
// Whether to show replies directly below
|
|
showRepliesBelow: (function() {
|
|
var reply_count, _ref;
|
|
reply_count = this.get('reply_count');
|
|
/* We don't show replies if there aren't any
|
|
*/
|
|
|
|
if (reply_count === 0) {
|
|
return false;
|
|
}
|
|
/* Always show replies if the setting `supress_reply_directly_below` is false.
|
|
*/
|
|
|
|
if (!Discourse.SiteSettings.supress_reply_directly_below) {
|
|
return true;
|
|
}
|
|
/*Always show replies if there's more than one
|
|
*/
|
|
|
|
if (reply_count > 1) {
|
|
return true;
|
|
}
|
|
/* If we have *exactly* one reply, we have to consider if it's directly below us
|
|
*/
|
|
|
|
if ((_ref = this.get('topic')) ? _ref.isReplyDirectlyBelow(this) : void 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}).property('reply_count')
|
|
});
|
|
|
|
window.Discourse.Post.reopenClass({
|
|
createActionSummary: function(result) {
|
|
var lookup;
|
|
if (result.actions_summary) {
|
|
lookup = Em.Object.create();
|
|
result.actions_summary = result.actions_summary.map(function(a) {
|
|
var actionSummary;
|
|
a.post = result;
|
|
a.actionType = Discourse.get("site").postActionTypeById(a.id);
|
|
actionSummary = Discourse.ActionSummary.create(a);
|
|
lookup.set(a.actionType.get('name_key'), actionSummary);
|
|
return actionSummary;
|
|
});
|
|
return result.set('actionByName', lookup);
|
|
}
|
|
},
|
|
create: function(obj, topic) {
|
|
var result;
|
|
result = this._super(obj);
|
|
this.createActionSummary(result);
|
|
if (obj.reply_to_user) {
|
|
result.set('reply_to_user', Discourse.User.create(obj.reply_to_user));
|
|
}
|
|
result.set('topic', topic);
|
|
return result;
|
|
},
|
|
deleteMany: function(posts) {
|
|
return jQuery.ajax("/posts/destroy_many", {
|
|
type: 'DELETE',
|
|
data: {
|
|
post_ids: posts.map(function(p) {
|
|
return p.get('id');
|
|
})
|
|
}
|
|
});
|
|
},
|
|
loadVersion: function(postId, version, callback) {
|
|
var _this = this;
|
|
return jQuery.getJSON("/posts/" + postId + ".json?version=" + version, function(result) {
|
|
return callback(Discourse.Post.create(result));
|
|
});
|
|
},
|
|
loadByPostNumber: function(topicId, postId, callback) {
|
|
var _this = this;
|
|
return jQuery.getJSON("/posts/by_number/" + topicId + "/" + postId + ".json", function(result) {
|
|
return callback(Discourse.Post.create(result));
|
|
});
|
|
},
|
|
loadQuote: function(postId) {
|
|
var promise,
|
|
_this = this;
|
|
promise = new RSVP.Promise();
|
|
jQuery.getJSON("/posts/" + postId + ".json", function(result) {
|
|
var post;
|
|
post = Discourse.Post.create(result);
|
|
return promise.resolve(Discourse.BBCode.buildQuoteBBCode(post, post.get('raw')));
|
|
});
|
|
return promise;
|
|
},
|
|
load: function(postId, callback) {
|
|
var _this = this;
|
|
return jQuery.getJSON("/posts/" + postId + ".json", function(result) {
|
|
return callback(Discourse.Post.create(result));
|
|
});
|
|
}
|
|
});
|
|
|
|
}).call(this);
|