mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Convert Discourse.Post to ES6 and use Store model
- Includes acceptance tests for composer (post, edit) - Supports acceptance testing of bootbox
This commit is contained in:
11
app/assets/javascripts/discourse/adapters/post.js.es6
Normal file
11
app/assets/javascripts/discourse/adapters/post.js.es6
Normal file
@@ -0,0 +1,11 @@
|
||||
import RestAdapter from 'discourse/adapters/rest';
|
||||
|
||||
export default RestAdapter.extend({
|
||||
|
||||
// GET /posts doesn't include a type
|
||||
find(store, type, findArgs) {
|
||||
return this._super(store, type, findArgs).then(function(result) {
|
||||
return {post: result};
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -61,7 +61,8 @@ export default DiscourseController.extend({
|
||||
if (postId) {
|
||||
this.set('model.loading', true);
|
||||
const composer = this;
|
||||
return Discourse.Post.load(postId).then(function(post) {
|
||||
|
||||
return this.store.find('post', postId).then(function(post) {
|
||||
const quote = Discourse.Quote.build(post, post.get("raw"));
|
||||
composer.appendBlockAtCursor(quote);
|
||||
composer.set('model.loading', false);
|
||||
@@ -412,7 +413,7 @@ export default DiscourseController.extend({
|
||||
composerModel.set('topic', opts.topic);
|
||||
}
|
||||
} else {
|
||||
composerModel = composerModel || Discourse.Composer.create();
|
||||
composerModel = composerModel || Discourse.Composer.create({ store: this.store });
|
||||
composerModel.open(opts);
|
||||
}
|
||||
|
||||
|
||||
@@ -323,7 +323,13 @@
|
||||
// Adds a listener callback to a DOM element which is fired on a specified
|
||||
// event.
|
||||
util.addEvent = function (elem, event, listener) {
|
||||
elem.addEventListener(event, listener, false);
|
||||
var wrapped = function() {
|
||||
var wrappedArgs = Array.prototype.slice(arguments);
|
||||
Ember.run(function() {
|
||||
listener.call(this, wrappedArgs);
|
||||
});
|
||||
};
|
||||
elem.addEventListener(event, wrapped, false);
|
||||
};
|
||||
|
||||
|
||||
@@ -904,7 +910,7 @@
|
||||
// TODO allow us to inject this in (its our debouncer)
|
||||
var debounce = function(func,wait,trickle) {
|
||||
var timeout = null;
|
||||
return function(){
|
||||
return function() {
|
||||
var context = this;
|
||||
var args = arguments;
|
||||
|
||||
@@ -924,8 +930,8 @@
|
||||
currentWait = wait;
|
||||
}
|
||||
|
||||
if (timeout) { clearTimeout(timeout); }
|
||||
timeout = setTimeout(later, currentWait);
|
||||
if (timeout) { Ember.run.cancel(timeout); }
|
||||
timeout = Ember.run.later(later, currentWait);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ const CLOSED = 'closed',
|
||||
const Composer = Discourse.Model.extend({
|
||||
|
||||
archetypes: function() {
|
||||
return Discourse.Site.currentProp('archetypes');
|
||||
return this.site.get('archetypes');
|
||||
}.property(),
|
||||
|
||||
creatingTopic: Em.computed.equal('action', CREATE_TOPIC),
|
||||
@@ -127,21 +127,16 @@ const Composer = Discourse.Model.extend({
|
||||
} else {
|
||||
// has a category? (when needed)
|
||||
return this.get('canCategorize') &&
|
||||
!Discourse.SiteSettings.allow_uncategorized_topics &&
|
||||
!this.siteSettings.allow_uncategorized_topics &&
|
||||
!this.get('categoryId') &&
|
||||
!Discourse.User.currentProp('staff');
|
||||
!this.user.get('staff');
|
||||
}
|
||||
}.property('loading', 'canEditTitle', 'titleLength', 'targetUsernames', 'replyLength', 'categoryId', 'missingReplyCharacters'),
|
||||
|
||||
/**
|
||||
Is the title's length valid?
|
||||
|
||||
@property titleLengthValid
|
||||
**/
|
||||
titleLengthValid: function() {
|
||||
if (Discourse.User.currentProp('admin') && this.get('post.static_doc') && this.get('titleLength') > 0) return true;
|
||||
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') <= Discourse.SiteSettings.max_topic_title_length);
|
||||
return (this.get('titleLength') <= this.siteSettings.max_topic_title_length);
|
||||
}.property('minimumTitleLength', 'titleLength', 'post.static_doc'),
|
||||
|
||||
// The icon for the save button
|
||||
@@ -194,9 +189,9 @@ const Composer = Discourse.Model.extend({
|
||||
**/
|
||||
minimumTitleLength: function() {
|
||||
if (this.get('privateMessage')) {
|
||||
return Discourse.SiteSettings.min_private_message_title_length;
|
||||
return this.siteSettings.min_private_message_title_length;
|
||||
} else {
|
||||
return Discourse.SiteSettings.min_topic_title_length;
|
||||
return this.siteSettings.min_topic_title_length;
|
||||
}
|
||||
}.property('privateMessage'),
|
||||
|
||||
@@ -216,12 +211,12 @@ const Composer = Discourse.Model.extend({
|
||||
**/
|
||||
minimumPostLength: function() {
|
||||
if( this.get('privateMessage') ) {
|
||||
return Discourse.SiteSettings.min_private_message_post_length;
|
||||
return this.siteSettings.min_private_message_post_length;
|
||||
} else if (this.get('topicFirstPost')) {
|
||||
// first post (topic body)
|
||||
return Discourse.SiteSettings.min_first_post_length;
|
||||
return this.siteSettings.min_first_post_length;
|
||||
} else {
|
||||
return Discourse.SiteSettings.min_post_length;
|
||||
return this.siteSettings.min_post_length;
|
||||
}
|
||||
}.property('privateMessage', 'topicFirstPost'),
|
||||
|
||||
@@ -249,7 +244,7 @@ const Composer = Discourse.Model.extend({
|
||||
_setupComposer: function() {
|
||||
const val = (Discourse.Mobile.mobileView ? false : (Discourse.KeyValueStore.get('composer.showPreview') || 'true'));
|
||||
this.set('showPreview', val === 'true');
|
||||
this.set('archetypeId', Discourse.Site.currentProp('default_archetype'));
|
||||
this.set('archetypeId', this.site.get('default_archetype'));
|
||||
}.on('init'),
|
||||
|
||||
/**
|
||||
@@ -349,15 +344,15 @@ const Composer = Discourse.Model.extend({
|
||||
|
||||
this.setProperties({
|
||||
categoryId: opts.categoryId || this.get('topic.category.id'),
|
||||
archetypeId: opts.archetypeId || Discourse.Site.currentProp('default_archetype'),
|
||||
archetypeId: opts.archetypeId || this.site.get('default_archetype'),
|
||||
metaData: opts.metaData ? Em.Object.create(opts.metaData) : null,
|
||||
reply: opts.reply || this.get("reply") || ""
|
||||
});
|
||||
|
||||
if (opts.postId) {
|
||||
this.set('loading', true);
|
||||
Discourse.Post.load(opts.postId).then(function(result) {
|
||||
composer.set('post', result);
|
||||
this.store.find('post', opts.postId).then(function(post) {
|
||||
composer.set('post', post);
|
||||
composer.set('loading', false);
|
||||
});
|
||||
}
|
||||
@@ -370,10 +365,10 @@ const Composer = Discourse.Model.extend({
|
||||
|
||||
this.setProperties(topicProps);
|
||||
|
||||
Discourse.Post.load(opts.post.get('id')).then(function(result) {
|
||||
this.store.find('post', opts.post.get('id')).then(function(post) {
|
||||
composer.setProperties({
|
||||
reply: result.get('raw'),
|
||||
originalText: result.get('raw'),
|
||||
reply: post.get('raw'),
|
||||
originalText: post.get('raw'),
|
||||
loading: false
|
||||
});
|
||||
});
|
||||
@@ -467,7 +462,7 @@ const Composer = Discourse.Model.extend({
|
||||
createPost(opts) {
|
||||
const post = this.get('post'),
|
||||
topic = this.get('topic'),
|
||||
currentUser = Discourse.User.current(),
|
||||
user = this.user,
|
||||
postStream = this.get('topic.postStream');
|
||||
|
||||
let addedToStream = false;
|
||||
@@ -477,17 +472,17 @@ const Composer = Discourse.Model.extend({
|
||||
imageSizes: opts.imageSizes,
|
||||
cooked: this.getCookedHtml(),
|
||||
reply_count: 0,
|
||||
name: currentUser.get('name'),
|
||||
display_username: currentUser.get('name'),
|
||||
username: currentUser.get('username'),
|
||||
user_id: currentUser.get('id'),
|
||||
user_title: currentUser.get('title'),
|
||||
uploaded_avatar_id: currentUser.get('uploaded_avatar_id'),
|
||||
user_custom_fields: currentUser.get('custom_fields'),
|
||||
post_type: Discourse.Site.currentProp('post_types.regular'),
|
||||
name: user.get('name'),
|
||||
display_username: user.get('name'),
|
||||
username: user.get('username'),
|
||||
user_id: user.get('id'),
|
||||
user_title: user.get('title'),
|
||||
uploaded_avatar_id: user.get('uploaded_avatar_id'),
|
||||
user_custom_fields: user.get('custom_fields'),
|
||||
post_type: this.site.get('post_types.regular'),
|
||||
actions_summary: [],
|
||||
moderator: currentUser.get('moderator'),
|
||||
admin: currentUser.get('admin'),
|
||||
moderator: user.get('moderator'),
|
||||
admin: user.get('admin'),
|
||||
yours: true,
|
||||
newPost: true,
|
||||
read: true
|
||||
@@ -520,7 +515,7 @@ const Composer = Discourse.Model.extend({
|
||||
// we would need to handle oneboxes and other bits that are not even in the
|
||||
// engine, staging will just cause a blank post to render
|
||||
if (!_.isEmpty(createdPost.get('cooked'))) {
|
||||
state = postStream.stagePost(createdPost, currentUser);
|
||||
state = postStream.stagePost(createdPost, user);
|
||||
|
||||
if(state === "alreadyStaging"){
|
||||
return;
|
||||
@@ -529,69 +524,64 @@ const Composer = Discourse.Model.extend({
|
||||
}
|
||||
}
|
||||
|
||||
const composer = this,
|
||||
promise = new Ember.RSVP.Promise(function(resolve, reject) {
|
||||
composer.set('composeState', SAVING);
|
||||
|
||||
createdPost.save(function(result) {
|
||||
let saving = true;
|
||||
|
||||
createdPost.updateFromJson(result);
|
||||
|
||||
if (topic) {
|
||||
// It's no longer a new post
|
||||
createdPost.set('newPost', false);
|
||||
topic.set('draft_sequence', result.draft_sequence);
|
||||
postStream.commitPost(createdPost);
|
||||
addedToStream = true;
|
||||
} else {
|
||||
// We created a new topic, let's show it.
|
||||
composer.set('composeState', CLOSED);
|
||||
saving = false;
|
||||
|
||||
// Update topic_count for the category
|
||||
const category = Discourse.Site.currentProp('categories').find(function(x) { return x.get('id') === (parseInt(createdPost.get('category'),10) || 1); });
|
||||
if (category) category.incrementProperty('topic_count');
|
||||
Discourse.notifyPropertyChange('globalNotice');
|
||||
}
|
||||
|
||||
composer.clearState();
|
||||
composer.set('createdPost', createdPost);
|
||||
|
||||
if (addedToStream) {
|
||||
composer.set('composeState', CLOSED);
|
||||
} else if (saving) {
|
||||
composer.set('composeState', SAVING);
|
||||
}
|
||||
|
||||
return resolve({ post: result });
|
||||
}, function(error) {
|
||||
// If an error occurs
|
||||
if (postStream) {
|
||||
postStream.undoPost(createdPost);
|
||||
}
|
||||
composer.set('composeState', OPEN);
|
||||
|
||||
// TODO extract error handling code
|
||||
let parsedError;
|
||||
try {
|
||||
const parsedJSON = $.parseJSON(error.responseText);
|
||||
if (parsedJSON.errors) {
|
||||
parsedError = parsedJSON.errors[0];
|
||||
} else if (parsedJSON.failed) {
|
||||
parsedError = parsedJSON.message;
|
||||
}
|
||||
}
|
||||
catch(ex) {
|
||||
parsedError = "Unknown error saving post, try again. Error: " + error.status + " " + error.statusText;
|
||||
}
|
||||
reject(parsedError);
|
||||
});
|
||||
});
|
||||
|
||||
const composer = this;
|
||||
composer.set('composeState', SAVING);
|
||||
composer.set("stagedPost", state === "staged" && createdPost);
|
||||
|
||||
return promise;
|
||||
return createdPost.save().then(function(result) {
|
||||
let saving = true;
|
||||
createdPost.updateFromJson(result);
|
||||
|
||||
if (topic) {
|
||||
// It's no longer a new post
|
||||
createdPost.set('newPost', false);
|
||||
topic.set('draft_sequence', result.draft_sequence);
|
||||
postStream.commitPost(createdPost);
|
||||
addedToStream = true;
|
||||
} else {
|
||||
// We created a new topic, let's show it.
|
||||
composer.set('composeState', CLOSED);
|
||||
saving = false;
|
||||
|
||||
// Update topic_count for the category
|
||||
const category = composer.site.get('categories').find(function(x) { return x.get('id') === (parseInt(createdPost.get('category'),10) || 1); });
|
||||
if (category) category.incrementProperty('topic_count');
|
||||
Discourse.notifyPropertyChange('globalNotice');
|
||||
}
|
||||
|
||||
composer.clearState();
|
||||
composer.set('createdPost', createdPost);
|
||||
|
||||
if (addedToStream) {
|
||||
composer.set('composeState', CLOSED);
|
||||
} else if (saving) {
|
||||
composer.set('composeState', SAVING);
|
||||
}
|
||||
|
||||
return { post: result };
|
||||
}).catch(function(error) {
|
||||
|
||||
// If an error occurs
|
||||
if (postStream) {
|
||||
postStream.undoPost(createdPost);
|
||||
}
|
||||
composer.set('composeState', OPEN);
|
||||
|
||||
// TODO extract error handling code
|
||||
let parsedError;
|
||||
try {
|
||||
const parsedJSON = $.parseJSON(error.responseText);
|
||||
if (parsedJSON.errors) {
|
||||
parsedError = parsedJSON.errors[0];
|
||||
} else if (parsedJSON.failed) {
|
||||
parsedError = parsedJSON.message;
|
||||
}
|
||||
}
|
||||
catch(ex) {
|
||||
parsedError = "Unknown error saving post, try again. Error: " + error.status + " " + error.statusText;
|
||||
}
|
||||
throw parsedError;
|
||||
});
|
||||
},
|
||||
|
||||
getCookedHtml() {
|
||||
@@ -604,7 +594,7 @@ const Composer = Discourse.Model.extend({
|
||||
// Do not save when there is no reply
|
||||
if (!this.get('reply')) return;
|
||||
// Do not save when the reply's length is too small
|
||||
if (this.get('replyLength') < Discourse.SiteSettings.min_post_length) return;
|
||||
if (this.get('replyLength') < this.siteSettings.min_post_length) return;
|
||||
|
||||
const data = {
|
||||
reply: this.get('reply'),
|
||||
@@ -673,6 +663,14 @@ Composer.reopenClass({
|
||||
}
|
||||
},
|
||||
|
||||
create(args) {
|
||||
args = args || {};
|
||||
args.user = args.user || Discourse.User.current();
|
||||
args.site = args.site || Discourse.Site.current();
|
||||
args.siteSettings = args.siteSettings || Discourse.SiteSettings;
|
||||
return this._super(args);
|
||||
},
|
||||
|
||||
serializeToTopic(fieldName, property) {
|
||||
if (!property) { property = fieldName; }
|
||||
_edit_topic_serializer[fieldName] = property;
|
||||
|
||||
@@ -1,20 +1,12 @@
|
||||
/**
|
||||
A data model representing a post in a topic
|
||||
const Post = Discourse.Model.extend({
|
||||
|
||||
@class Post
|
||||
@extends Discourse.Model
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.Post = Discourse.Model.extend({
|
||||
|
||||
init: function() {
|
||||
init() {
|
||||
this.set('replyHistory', []);
|
||||
},
|
||||
|
||||
shareUrl: function() {
|
||||
var user = Discourse.User.current();
|
||||
var userSuffix = user ? '?u=' + user.get('username_lower') : '';
|
||||
const user = Discourse.User.current();
|
||||
const userSuffix = user ? '?u=' + user.get('username_lower') : '';
|
||||
|
||||
if (this.get('firstPost')) {
|
||||
return this.get('topic.url') + userSuffix;
|
||||
@@ -33,7 +25,7 @@ Discourse.Post = Discourse.Model.extend({
|
||||
userDeleted: Em.computed.empty('user_id'),
|
||||
|
||||
showName: function() {
|
||||
var name = this.get('name');
|
||||
const name = this.get('name');
|
||||
return name && (name !== this.get('username')) && Discourse.SiteSettings.display_name_on_posts;
|
||||
}.property('name', 'username'),
|
||||
|
||||
@@ -69,17 +61,17 @@ Discourse.Post = Discourse.Model.extend({
|
||||
}.property("user_id"),
|
||||
|
||||
wikiChanged: function() {
|
||||
var data = { wiki: this.get("wiki") };
|
||||
const data = { wiki: this.get("wiki") };
|
||||
this._updatePost("wiki", data);
|
||||
}.observes('wiki'),
|
||||
|
||||
postTypeChanged: function () {
|
||||
var data = { post_type: this.get("post_type") };
|
||||
const data = { post_type: this.get("post_type") };
|
||||
this._updatePost("post_type", data);
|
||||
}.observes("post_type"),
|
||||
|
||||
_updatePost: function (field, data) {
|
||||
var self = this;
|
||||
_updatePost(field, data) {
|
||||
const self = this;
|
||||
Discourse.ajax("/posts/" + this.get("id") + "/" + field, {
|
||||
type: "PUT",
|
||||
data: data
|
||||
@@ -103,7 +95,7 @@ Discourse.Post = Discourse.Model.extend({
|
||||
editCount: function() { return this.get('version') - 1; }.property('version'),
|
||||
|
||||
flagsAvailable: function() {
|
||||
var post = this;
|
||||
const post = this;
|
||||
return Discourse.Site.currentProp('flagTypes').filter(function(item) {
|
||||
return post.get("actionByName." + item.get('name_key') + ".can_act");
|
||||
});
|
||||
@@ -119,9 +111,8 @@ Discourse.Post = Discourse.Model.extend({
|
||||
});
|
||||
}.property('actions_summary.@each.users', 'actions_summary.@each.count'),
|
||||
|
||||
// Save a post and call the callback when done.
|
||||
save: function(complete, error) {
|
||||
var self = this;
|
||||
save() {
|
||||
const self = this;
|
||||
if (!this.get('newPost')) {
|
||||
// We're updating a post
|
||||
return Discourse.ajax("/posts/" + (this.get('id')), {
|
||||
@@ -135,19 +126,17 @@ Discourse.Post = Discourse.Model.extend({
|
||||
// If we received a category update, update it
|
||||
self.set('version', result.post.version);
|
||||
if (result.category) Discourse.Site.current().updateCategory(result.category);
|
||||
if (complete) complete(Discourse.Post.create(result.post));
|
||||
}).catch(function(result) {
|
||||
// Post failed to update
|
||||
if (error) error(result);
|
||||
return Discourse.Post.create(result.post);
|
||||
});
|
||||
|
||||
} else {
|
||||
// We're saving a post
|
||||
var data = this.getProperties(Discourse.Composer.serializedFieldsForCreate());
|
||||
const data = this.getProperties(Discourse.Composer.serializedFieldsForCreate());
|
||||
data.reply_to_post_number = this.get('reply_to_post_number');
|
||||
data.image_sizes = this.get('imageSizes');
|
||||
data.nested_post = true;
|
||||
|
||||
var metaData = this.get('metaData');
|
||||
const metaData = this.get('metaData');
|
||||
// Put the metaData into the request
|
||||
if (metaData) {
|
||||
data.meta_data = {};
|
||||
@@ -158,34 +147,22 @@ Discourse.Post = Discourse.Model.extend({
|
||||
type: 'POST',
|
||||
data: data
|
||||
}).then(function(result) {
|
||||
// Post created
|
||||
if (complete) complete(Discourse.Post.create(result));
|
||||
}).catch(function(result) {
|
||||
// Failed to create a post
|
||||
if (error) error(result);
|
||||
return Discourse.Post.create(result.post);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Expands the first post's content, if embedded and shortened.
|
||||
|
||||
@method expandFirstPost
|
||||
**/
|
||||
expand: function() {
|
||||
var self = this;
|
||||
// Expands the first post's content, if embedded and shortened.
|
||||
expand() {
|
||||
const self = this;
|
||||
return Discourse.ajax("/posts/" + this.get('id') + "/expand-embed").then(function(post) {
|
||||
self.set('cooked', "<section class='expanded-embed'>" + post.cooked + "</section>" );
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Recover a deleted post
|
||||
|
||||
@method recover
|
||||
**/
|
||||
recover: function() {
|
||||
var post = this;
|
||||
// Recover a deleted post
|
||||
recover() {
|
||||
const post = this;
|
||||
post.setProperties({
|
||||
deleted_at: null,
|
||||
deleted_by: null,
|
||||
@@ -207,11 +184,8 @@ Discourse.Post = Discourse.Model.extend({
|
||||
/**
|
||||
Changes the state of the post to be deleted. Does not call the server, that should be
|
||||
done elsewhere.
|
||||
|
||||
@method setDeletedState
|
||||
@param {Discourse.User} deletedBy The user deleting the post
|
||||
**/
|
||||
setDeletedState: function(deletedBy) {
|
||||
setDeletedState(deletedBy) {
|
||||
this.set('oldCooked', this.get('cooked'));
|
||||
|
||||
// Moderators can delete posts. Users can only trigger a deleted at message, unless delete_removed_posts_after is 0.
|
||||
@@ -237,10 +211,8 @@ Discourse.Post = Discourse.Model.extend({
|
||||
Changes the state of the post to NOT be deleted. Does not call the server.
|
||||
This can only be called after setDeletedState was called, but the delete
|
||||
failed on the server.
|
||||
|
||||
@method undoDeletedState
|
||||
**/
|
||||
undoDeleteState: function() {
|
||||
undoDeleteState() {
|
||||
if (this.get('oldCooked')) {
|
||||
this.setProperties({
|
||||
deleted_at: null,
|
||||
@@ -253,13 +225,7 @@ Discourse.Post = Discourse.Model.extend({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Deletes a post
|
||||
|
||||
@method destroy
|
||||
@param {Discourse.User} deletedBy The user deleting the post
|
||||
**/
|
||||
destroy: function(deletedBy) {
|
||||
destroy(deletedBy) {
|
||||
this.setDeletedState(deletedBy);
|
||||
return Discourse.ajax("/posts/" + this.get('id'), {
|
||||
data: { context: window.location.pathname },
|
||||
@@ -270,14 +236,11 @@ Discourse.Post = Discourse.Model.extend({
|
||||
/**
|
||||
Updates a post from another's attributes. This will normally happen when a post is loading but
|
||||
is already found in an identity map.
|
||||
|
||||
@method updateFromPost
|
||||
@param {Discourse.Post} otherPost The post we're updating from
|
||||
**/
|
||||
updateFromPost: function(otherPost) {
|
||||
var self = this;
|
||||
updateFromPost(otherPost) {
|
||||
const self = this;
|
||||
Object.keys(otherPost).forEach(function (key) {
|
||||
var value = otherPost[key],
|
||||
let value = otherPost[key],
|
||||
oldValue = self[key];
|
||||
|
||||
if (key === "replyHistory") {
|
||||
@@ -287,7 +250,7 @@ Discourse.Post = Discourse.Model.extend({
|
||||
if (!value) { value = null; }
|
||||
if (!oldValue) { oldValue = null; }
|
||||
|
||||
var skip = false;
|
||||
let skip = false;
|
||||
if (typeof value !== "function" && oldValue !== value) {
|
||||
// wishing for an identity map
|
||||
if (key === "reply_to_user" && value && oldValue) {
|
||||
@@ -304,17 +267,14 @@ Discourse.Post = Discourse.Model.extend({
|
||||
/**
|
||||
Updates a post from a JSON packet. This is normally done after the post is saved to refresh any
|
||||
attributes.
|
||||
|
||||
@method updateFromJson
|
||||
@param {Object} obj The Json data to update with
|
||||
**/
|
||||
updateFromJson: function(obj) {
|
||||
updateFromJson(obj) {
|
||||
if (!obj) return;
|
||||
|
||||
var skip, oldVal;
|
||||
let skip, oldVal;
|
||||
|
||||
// Update all the properties
|
||||
var post = this;
|
||||
const post = this;
|
||||
_.each(obj, function(val,key) {
|
||||
if (key !== 'actions_summary'){
|
||||
oldVal = post[key];
|
||||
@@ -336,12 +296,11 @@ Discourse.Post = Discourse.Model.extend({
|
||||
// Rebuild actions summary
|
||||
this.set('actions_summary', Em.A());
|
||||
if (obj.actions_summary) {
|
||||
var lookup = Em.Object.create();
|
||||
const lookup = Em.Object.create();
|
||||
_.each(obj.actions_summary,function(a) {
|
||||
var actionSummary;
|
||||
a.post = post;
|
||||
a.actionType = Discourse.Site.current().postActionTypeById(a.id);
|
||||
actionSummary = Discourse.ActionSummary.create(a);
|
||||
const actionSummary = Discourse.ActionSummary.create(a);
|
||||
post.get('actions_summary').pushObject(actionSummary);
|
||||
lookup.set(a.actionType.get('name_key'), actionSummary);
|
||||
});
|
||||
@@ -350,7 +309,7 @@ Discourse.Post = Discourse.Model.extend({
|
||||
},
|
||||
|
||||
// Load replies to this post
|
||||
loadReplies: function() {
|
||||
loadReplies() {
|
||||
if(this.get('loadingReplies')){
|
||||
return;
|
||||
}
|
||||
@@ -358,12 +317,12 @@ Discourse.Post = Discourse.Model.extend({
|
||||
this.set('loadingReplies', true);
|
||||
this.set('replies', []);
|
||||
|
||||
var self = this;
|
||||
const self = this;
|
||||
return Discourse.ajax("/posts/" + (this.get('id')) + "/replies")
|
||||
.then(function(loaded) {
|
||||
var replies = self.get('replies');
|
||||
const replies = self.get('replies');
|
||||
_.each(loaded,function(reply) {
|
||||
var post = Discourse.Post.create(reply);
|
||||
const post = Discourse.Post.create(reply);
|
||||
post.set('topic', self.get('topic'));
|
||||
replies.pushObject(post);
|
||||
});
|
||||
@@ -375,7 +334,7 @@ Discourse.Post = Discourse.Model.extend({
|
||||
|
||||
// Whether to show replies directly below
|
||||
showRepliesBelow: function() {
|
||||
var replyCount = this.get('reply_count');
|
||||
const replyCount = this.get('reply_count');
|
||||
|
||||
// We don't show replies if there aren't any
|
||||
if (replyCount === 0) return false;
|
||||
@@ -387,13 +346,13 @@ Discourse.Post = Discourse.Model.extend({
|
||||
if (replyCount > 1) return true;
|
||||
|
||||
// If we have *exactly* one reply, we have to consider if it's directly below us
|
||||
var topic = this.get('topic');
|
||||
const topic = this.get('topic');
|
||||
return !topic.isReplyDirectlyBelow(this);
|
||||
|
||||
}.property('reply_count'),
|
||||
|
||||
expandHidden: function() {
|
||||
var self = this;
|
||||
expandHidden() {
|
||||
const self = this;
|
||||
return Discourse.ajax("/posts/" + this.get('id') + "/cooked.json").then(function (result) {
|
||||
self.setProperties({
|
||||
cooked: result.cooked,
|
||||
@@ -402,17 +361,17 @@ Discourse.Post = Discourse.Model.extend({
|
||||
});
|
||||
},
|
||||
|
||||
rebake: function () {
|
||||
rebake() {
|
||||
return Discourse.ajax("/posts/" + this.get("id") + "/rebake", { type: "PUT" });
|
||||
},
|
||||
|
||||
unhide: function () {
|
||||
unhide() {
|
||||
return Discourse.ajax("/posts/" + this.get("id") + "/unhide", { type: "PUT" });
|
||||
},
|
||||
|
||||
toggleBookmark: function() {
|
||||
var self = this,
|
||||
bookmarkedTopic;
|
||||
toggleBookmark() {
|
||||
const self = this;
|
||||
let bookmarkedTopic;
|
||||
|
||||
this.toggleProperty("bookmarked");
|
||||
|
||||
@@ -435,16 +394,16 @@ Discourse.Post = Discourse.Model.extend({
|
||||
}
|
||||
});
|
||||
|
||||
Discourse.Post.reopenClass({
|
||||
Post.reopenClass({
|
||||
|
||||
createActionSummary: function(result) {
|
||||
createActionSummary(result) {
|
||||
if (result.actions_summary) {
|
||||
var lookup = Em.Object.create();
|
||||
const lookup = Em.Object.create();
|
||||
// this area should be optimized, it is creating way too many objects per post
|
||||
result.actions_summary = result.actions_summary.map(function(a) {
|
||||
a.post = result;
|
||||
a.actionType = Discourse.Site.current().postActionTypeById(a.id);
|
||||
var actionSummary = Discourse.ActionSummary.create(a);
|
||||
const actionSummary = Discourse.ActionSummary.create(a);
|
||||
lookup[a.actionType.name_key] = actionSummary;
|
||||
return actionSummary;
|
||||
});
|
||||
@@ -452,8 +411,8 @@ Discourse.Post.reopenClass({
|
||||
}
|
||||
},
|
||||
|
||||
create: function(obj) {
|
||||
var result = this._super.apply(this, arguments);
|
||||
create(obj) {
|
||||
const result = this._super.apply(this, arguments);
|
||||
this.createActionSummary(result);
|
||||
if (obj && obj.reply_to_user) {
|
||||
result.set('reply_to_user', Discourse.User.create(obj.reply_to_user));
|
||||
@@ -461,14 +420,14 @@ Discourse.Post.reopenClass({
|
||||
return result;
|
||||
},
|
||||
|
||||
updateBookmark: function(postId, bookmarked) {
|
||||
updateBookmark(postId, bookmarked) {
|
||||
return Discourse.ajax("/posts/" + postId + "/bookmark", {
|
||||
type: 'PUT',
|
||||
data: { bookmarked: bookmarked }
|
||||
});
|
||||
},
|
||||
|
||||
deleteMany: function(selectedPosts, selectedReplies) {
|
||||
deleteMany(selectedPosts, selectedReplies) {
|
||||
return Discourse.ajax("/posts/destroy_many", {
|
||||
type: 'DELETE',
|
||||
data: {
|
||||
@@ -478,37 +437,33 @@ Discourse.Post.reopenClass({
|
||||
});
|
||||
},
|
||||
|
||||
loadRevision: function(postId, version) {
|
||||
loadRevision(postId, version) {
|
||||
return Discourse.ajax("/posts/" + postId + "/revisions/" + version + ".json").then(function (result) {
|
||||
return Ember.Object.create(result);
|
||||
});
|
||||
},
|
||||
|
||||
hideRevision: function(postId, version) {
|
||||
hideRevision(postId, version) {
|
||||
return Discourse.ajax("/posts/" + postId + "/revisions/" + version + "/hide", { type: 'PUT' });
|
||||
},
|
||||
|
||||
showRevision: function(postId, version) {
|
||||
showRevision(postId, version) {
|
||||
return Discourse.ajax("/posts/" + postId + "/revisions/" + version + "/show", { type: 'PUT' });
|
||||
},
|
||||
|
||||
loadQuote: function(postId) {
|
||||
loadQuote(postId) {
|
||||
return Discourse.ajax("/posts/" + postId + ".json").then(function (result) {
|
||||
var post = Discourse.Post.create(result);
|
||||
const post = Discourse.Post.create(result);
|
||||
return Discourse.Quote.build(post, post.get('raw'));
|
||||
});
|
||||
},
|
||||
|
||||
loadRawEmail: function(postId) {
|
||||
loadRawEmail(postId) {
|
||||
return Discourse.ajax("/posts/" + postId + "/raw-email").then(function (result) {
|
||||
return result.raw_email;
|
||||
});
|
||||
},
|
||||
|
||||
load: function(postId) {
|
||||
return Discourse.ajax("/posts/" + postId + ".json").then(function (result) {
|
||||
return Discourse.Post.create(result);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
export default Post;
|
||||
@@ -25,6 +25,7 @@
|
||||
//= require ./discourse/lib/safari-hacks
|
||||
//= require_tree ./discourse/adapters
|
||||
//= require ./discourse/models/model
|
||||
//= require ./discourse/models/post
|
||||
//= require ./discourse/models/user_action
|
||||
//= require ./discourse/models/composer
|
||||
//= require ./discourse/models/post-stream
|
||||
|
||||
@@ -336,7 +336,11 @@ class PostsController < ApplicationController
|
||||
# doesn't return the post as the root JSON object, but as a nested object.
|
||||
# If a param is present it uses that result structure.
|
||||
def backwards_compatible_json(json_obj, success)
|
||||
json_obj = json_obj[:post] || json_obj['post'] unless params[:nested_post]
|
||||
json_obj.symbolize_keys!
|
||||
if params[:nested_post].blank? && json_obj[:errors].blank?
|
||||
json_obj = json_obj[:post]
|
||||
end
|
||||
|
||||
render json: json_obj, status: (!!success) ? 200 : 422
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user